Hi,

I've run into a couple of strict aliasing issues with type casts for the vtab
struct. Can anyone with more C experience than me comment on these?

For the "r_jiba1" test case in

http://hg.cython.org/cython-devel/file/e21391d5f23a/tests/run/r_jiba1.pyx

Cython currently generates this in the tp_new function of the Norwegian class:

  *(struct __pyx_vtabstruct_7r_jiba1_Norwegian **)&p->__pyx_base.__pyx_vtab =
        __pyx_vtabptr_7r_jiba1_Norwegian;

which results in this strict aliasing warning with gcc 4.1:

  r_jiba1.c: In function '__pyx_tp_new_7r_jiba1_Norwegian':
  r_jiba1.c:596: warning: dereferencing type-punned pointer will break
          strict-aliasing rules

It goes away when I change it to this (patch is attached):

  p->__pyx_base.__pyx_vtab =
   (struct __pyx_vtabstruct_7r_jiba1_Parrot*)__pyx_vtabptr_7r_jiba1_Norwegian;

Parrot is the base type here. Since these changes usually tend to break some
compiler somewhere, I hesitate to apply the patch right away, though...


Similar things happen when the C methods are initialised in the module init
function. Currently, we have:

  *(void(**)(void))&__pyx_vtable_7r_jiba1_Parrot.describe =
                    (void(*)(void))__pyx_f_7r_jiba1_6Parrot_describe;
  *(void(**)(void))&__pyx_vtable_7r_jiba1_Norwegian.__pyx_base.describe =
                    (void(*)(void))__pyx_f_7r_jiba1_9Norwegian_describe;

and the resulting warning is:

  r_jiba1.c: In function 'PyInit_r_jiba1':
  r_jiba1.c:800: warning: dereferencing type-punned pointer will break
          strict-aliasing rules
  r_jiba1.c:807: warning: dereferencing type-punned pointer will break
          strict-aliasing rules

The problem here is mostly the "self" argument, which has the type of the
concrete class for each subtype. The code that generates this in the
generate_exttype_vtable_init_code() function in ModuleNode.py has the type
casts hard-coded. What would be the right thing to do here? Cast one of the
functions (rhs?) to the type of the other?

Any help is appreciated.

Thanks,
Stefan

diff -r e21391d5f23a Cython/Compiler/ModuleNode.py
--- a/Cython/Compiler/ModuleNode.py	Thu Jun 12 09:28:56 2008 +0200
+++ b/Cython/Compiler/ModuleNode.py	Thu Jun 12 10:33:45 2008 +0200
@@ -821,10 +821,13 @@ class ModuleNode(Nodes.Node, Nodes.Block
         #if need_self_cast:
         #	self.generate_self_cast(scope, code)
         if type.vtabslot_cname:
-            code.putln("*(struct %s **)&p->%s = %s;" % (
-                type.vtabstruct_cname,
+            if base_type:
+                struct_type_cast = "(struct %s*)" % base_type.vtabstruct_cname
+            else:
+                struct_type_cast = ""
+            code.putln("p->%s = %s%s;" % (
                 type.vtabslot_cname,
-                type.vtabptr_cname))
+                struct_type_cast, type.vtabptr_cname))
         for entry in py_attrs:
             if entry.name == "__weakref__":
                 code.putln("p->%s = 0;" % entry.cname)
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to