[libvirt] [PATCH 1/2] util: Turn virFirewallAddRule() into a macro

Andrea Bolognani abologna at redhat.com
Mon Jan 2 18:15:30 UTC 2017


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




More information about the libvir-list mailing list