Commits

Tom Nixon  committed 272c01a

Generate correct type name for pointers to arrays.

Previously, get_c_name("a") on the type "int (*)[5]" would return "int *[5]".
This caused "incompatible type" errors when verifying structs containing
pointers to arrays.

A partial workaround for this bug was originally made in vengine_*; this has
been removed.

  • Participants
  • Parent commits 39e5ad4

Comments (0)

Files changed (4)

File cffi/model.py

             brackets = '[]'
         else:
             brackets = '[%d]' % self.length
-        return self.item._get_c_name(replace_with + brackets)
+        return self.item._get_c_name('(%s)%s' % (replace_with, brackets))
 
     def build_backend_type(self, ffi, finishlist):
         self.item.get_cached_btype(ffi, finishlist)   # force the item BType

File cffi/vengine_cpy.py

                 # accept all integers, but complain on float or double
                 prnt('  (void)((p->%s) << 1);' % fname)
             else:
-                # only accept exactly the type declared.  Note the parentheses
-                # around the '*tmp' below.  In most cases they are not needed
-                # but don't hurt --- except test_struct_array_field.
+                # only accept exactly the type declared.
                 try:
                     prnt('  { %s = &p->%s; (void)tmp; }' % (
-                        ftype.get_c_name('(*tmp)', 'field %r'%fname), fname))
+                        ftype.get_c_name('*tmp', 'field %r'%fname), fname))
                 except ffiplatform.VerificationError as e:
                     prnt('  /* %s */' % str(e))   # cannot verify it, ignore
         prnt('}')

File cffi/vengine_gen.py

                 # accept all integers, but complain on float or double
                 prnt('  (void)((p->%s) << 1);' % fname)
             else:
-                # only accept exactly the type declared.  Note the parentheses
-                # around the '*tmp' below.  In most cases they are not needed
-                # but don't hurt --- except test_struct_array_field.
+                # only accept exactly the type declared.
                 try:
                     prnt('  { %s = &p->%s; (void)tmp; }' % (
-                        ftype.get_c_name('(*tmp)', 'field %r'%fname), fname))
+                        ftype.get_c_name('*tmp', 'field %r'%fname), fname))
                 except ffiplatform.VerificationError as e:
                     prnt('  /* %s */' % str(e))   # cannot verify it, ignore
         prnt('}')

File testing/test_verify.py

     s = ffi.new("struct foo_s *")
     assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int')
 
+def test_struct_ptr_to_array_field():
+    ffi = FFI()
+    ffi.cdef("struct foo_s { int (*a)[17]; ...; };")
+    ffi.verify("struct foo_s { int x; int (*a)[17]; int y; };")
+    assert ffi.sizeof('struct foo_s') == 2 * ffi.sizeof('int') + ffi.sizeof('int(*)[17]')
+    s = ffi.new("struct foo_s *")
+    assert ffi.sizeof(s.a) == ffi.sizeof('int(*)[17]')
+
 def test_struct_with_bitfield_exact():
     ffi = FFI()
     ffi.cdef("struct foo_s { int a:2, b:3; };")