[Spice-devel] [RFC] codegen+demarshal: cast to void** through a temporary

Alon Levy alevy at redhat.com
Thu Jul 29 09:20:49 PDT 2010


Changes
 var = (void**)&val;
Into
 {
  typeof val* p = &val;
  var = (void**)p;
 }

Which fixes these warnings (we compile with -Werror, any warning breaks compile):
 warning: dereferencing type-punned pointer will break strict-aliasing rules

Warnings were triggered by gcc 4.2.1 used by scratchbox for n900 development.

Produced code changes (viewed through disassembly of generated_demarshallers1.o)
appear totally minor.

Should this be fixed by making use of a union? i.e. something like
{
 void** p;
 uint8_t** p_uint8;
 ... (if other types are required)
}
?

---
 python_modules/codegen.py   |   14 ++++++++++++++
 python_modules/demarshal.py |    4 ++--
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/python_modules/codegen.py b/python_modules/codegen.py
index 03c67e6..fe55e91 100644
--- a/python_modules/codegen.py
+++ b/python_modules/codegen.py
@@ -160,6 +160,20 @@ class CodeWriter:
         self.newline()
         return self
 
+    def assign_voidpp(self, var, val):
+        """
+        The direct approach is:
+            var = (void**)&val;
+        and produces this warning if typeof val == uint8_t*
+            warning: dereferencing type-punned pointer will break strict-aliasing rules
+        The solution is to use a temp variable (hidden within a scope) and typeof
+        operator for it's type.
+        """
+        with self.block(""):
+            self.variable_def("typeof %s*" % val, "p = &%s" % val)
+            self.assign(var, "(void **)p")
+        return self
+
     def increment(self, var, val):
         self.write("%s += %s" % (var, val))
         self.write(";")
diff --git a/python_modules/demarshal.py b/python_modules/demarshal.py
index cbe3599..9df5a6f 100644
--- a/python_modules/demarshal.py
+++ b/python_modules/demarshal.py
@@ -821,7 +821,7 @@ def write_array_parser(writer, member, nelements, array, dest, scope):
                 scope.variable_def("void **", "ptr_array")
                 scope.variable_def("int", "ptr_array_index")
                 writer.assign("ptr_array_index", 0)
-                writer.assign("ptr_array", "(void **)%s" % array_start)
+                writer.assign_voidpp("ptr_array", array_start)
                 writer.increment("end", "sizeof(void *) * %s" % nelements)
                 array_start = "end"
                 array_pos = "*(%s *)end" % (element_type.c_type())
@@ -852,7 +852,7 @@ def write_parse_pointer_core(writer, target_type, offset, at_end, dest, member_n
         writer.assign("ptr_info[n_ptr].dest", "(void **)end")
         writer.increment("end", "sizeof(void *)");
     else:
-        writer.assign("ptr_info[n_ptr].dest", "(void **)&%s" % dest.get_ref(member_name))
+        writer.assign_voidpp("ptr_info[n_ptr].dest", dest.get_ref(member_name))
     if target_type.is_array():
         nelements = read_array_len(writer, member_name, target_type, dest, scope, True)
         writer.assign("ptr_info[n_ptr].nelements", nelements)
-- 
1.5.6.1



More information about the Spice-devel mailing list