util: Turn virFirewallAddRule() into a macro

Clang 3.9 refuses to compile the existing code with the
following error:

  util/virfirewall.c:425:20: error: passing an object that undergoes
                             default argument promotion to 'va_start'
                             has undefined behavior [-Werror,-Wvarargs]
      va_start(args, layer);
                     ^
  util/virfirewall.c:420:37: note: parameter of type 'virFirewallLayer'
                             is declared here
                     virFirewallLayer layer,
                                      ^

This happens because 'layer' is of type virFirewallLayer, which
is an enum type and not a standard type such as eg. void* or int.

To solve the issue, turn virFirewallAddRule() from a very thin
wrapper around virFirewallAddRuleFullV() to a macro that expands
to a call to virFirewallAddRuleFull() - itself a very thin wrapper
around the aforementioned virFirewallAddRuleFullV() - with no loss
of functionality or type safety.
This commit is contained in:
Andrea Bolognani 2017-01-02 19:15:30 +01:00
parent 7f7d990483
commit b9cc24839b
3 changed files with 12 additions and 28 deletions

View File

@ -1624,7 +1624,6 @@ virFindFileInPath;
# util/virfirewall.h
virFirewallAddRule;
virFirewallAddRuleFull;
virFirewallApply;
virFirewallFree;

View File

@ -405,29 +405,6 @@ virFirewallAddRuleFullV(virFirewallPtr firewall,
return NULL;
}
/**
* virFirewallAddRule:
* @firewall: firewall ruleset to add to
* @layer: the firewall layer to change
* @...: NULL terminated list of strings for the rule
*
* Add any type of rule to the firewall ruleset.
*
* Returns the new rule
*/
virFirewallRulePtr
virFirewallAddRule(virFirewallPtr firewall,
virFirewallLayer layer,
...)
{
virFirewallRulePtr rule;
va_list args;
va_start(args, layer);
rule = virFirewallAddRuleFullV(firewall, layer, false, NULL, NULL, args);
va_end(args);
return rule;
}
/**
* virFirewallAddRuleFull:

View File

@ -44,10 +44,18 @@ virFirewallPtr virFirewallNew(void);
void virFirewallFree(virFirewallPtr firewall);
virFirewallRulePtr virFirewallAddRule(virFirewallPtr firewall,
virFirewallLayer layer,
...)
ATTRIBUTE_SENTINEL;
/**
* virFirewallAddRule:
* @firewall: firewall ruleset to add to
* @layer: the firewall layer to change
* @...: NULL terminated list of strings for the rule
*
* Add any type of rule to the firewall ruleset.
*
* Returns the new rule
*/
#define virFirewallAddRule(firewall, layer, ...) \
virFirewallAddRuleFull(firewall, layer, false, NULL, NULL, __VA_ARGS__)
typedef int (*virFirewallQueryCallback)(virFirewallPtr firewall,
const char *const *lines,