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 only seems to be required on very specific combinations of Clang and host OS, eg. I need it on Clang 3.9 / Fedora rawhide but not on Clang 3.8 or 4.0 / Debian sid. src/libvirt_private.syms | 1 - src/util/virfirewall.c | 23 ----------------------- src/util/virfirewall.h | 16 ++++++++++++---- 3 files changed, 12 insertions(+), 28 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 2d23e462d..01118730b 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1624,7 +1624,6 @@ virFindFileInPath; # util/virfirewall.h -virFirewallAddRule; virFirewallAddRuleFull; virFirewallApply; virFirewallFree; diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c index 3f976186a..4de38d592 100644 --- a/src/util/virfirewall.c +++ b/src/util/virfirewall.c @@ -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: diff --git a/src/util/virfirewall.h b/src/util/virfirewall.h index dbf397537..5248d6003 100644 --- a/src/util/virfirewall.h +++ b/src/util/virfirewall.h @@ -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, -- 2.11.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list