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