[pypy-commit] cffi default: Bah, all unions crash verify(). Fixed.

arigo noreply at buildbot.pypy.org
Sun Aug 26 12:25:23 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r898:b5d6c4c2ca88
Date: 2012-08-26 12:25 +0200
http://bitbucket.org/cffi/cffi/changeset/b5d6c4c2ca88/

Log:	Bah, all unions crash verify(). Fixed.

diff --git a/cffi/vengine_cpy.py b/cffi/vengine_cpy.py
--- a/cffi/vengine_cpy.py
+++ b/cffi/vengine_cpy.py
@@ -338,18 +338,25 @@
     # named structs
 
     _generate_cpy_struct_collecttype = _generate_nothing
-
     def _generate_cpy_struct_decl(self, tp, name):
         assert name == tp.name
         self._generate_struct_or_union_decl(tp, 'struct', name)
-
     def _generate_cpy_struct_method(self, tp, name):
         self._generate_struct_or_union_method(tp, 'struct', name)
-
     def _loading_cpy_struct(self, tp, name, module):
         self._loading_struct_or_union(tp, 'struct', name, module)
+    def _loaded_cpy_struct(self, tp, name, module, **kwds):
+        self._loaded_struct_or_union(tp)
 
-    def _loaded_cpy_struct(self, tp, name, module, **kwds):
+    _generate_cpy_union_collecttype = _generate_nothing
+    def _generate_cpy_union_decl(self, tp, name):
+        assert name == tp.name
+        self._generate_struct_or_union_decl(tp, 'union', name)
+    def _generate_cpy_union_method(self, tp, name):
+        self._generate_struct_or_union_method(tp, 'union', name)
+    def _loading_cpy_union(self, tp, name, module):
+        self._loading_struct_or_union(tp, 'union', name, module)
+    def _loaded_cpy_union(self, tp, name, module, **kwds):
         self._loaded_struct_or_union(tp)
 
     def _generate_struct_or_union_decl(self, tp, prefix, name):
@@ -382,7 +389,7 @@
         prnt('%s(PyObject *self, PyObject *noarg)' % (layoutfuncname,))
         prnt('{')
         prnt('  struct _cffi_aligncheck { char x; %s y; };' % cname)
-        if tp.partial:
+        if isinstance(tp, model.StructType) and tp.partial:
             prnt('  static Py_ssize_t nums[] = {')
             prnt('    sizeof(%s),' % cname)
             prnt('    offsetof(struct _cffi_aligncheck, y),')
@@ -444,7 +451,7 @@
             raise ffiplatform.VerificationError(
                 "incompatible layout for %s" % cname)
         elif layout is True:
-            assert not tp.partial
+            assert isinstance(tp, model.UnionType) or not tp.partial
         else:
             totalsize = layout[0]
             totalalignment = layout[1]
diff --git a/cffi/vengine_gen.py b/cffi/vengine_gen.py
--- a/cffi/vengine_gen.py
+++ b/cffi/vengine_gen.py
@@ -172,6 +172,16 @@
     def _loaded_gen_struct(self, tp, name, module, **kwds):
         self._loaded_struct_or_union(tp)
 
+    def _generate_gen_union_decl(self, tp, name):
+        assert name == tp.name
+        self._generate_struct_or_union_decl(tp, 'union', name)
+
+    def _loading_gen_union(self, tp, name, module):
+        self._loading_struct_or_union(tp, 'union', name, module)
+
+    def _loaded_gen_union(self, tp, name, module, **kwds):
+        self._loaded_struct_or_union(tp)
+
     def _generate_struct_or_union_decl(self, tp, prefix, name):
         if tp.fldnames is None:
             return     # nothing to do with opaque structs
@@ -202,7 +212,7 @@
         prnt('ssize_t %s(ssize_t i)' % (layoutfuncname,))
         prnt('{')
         prnt('  struct _cffi_aligncheck { char x; %s y; };' % cname)
-        if tp.partial:
+        if isinstance(tp, model.StructType) and tp.partial:
             prnt('  static ssize_t nums[] = {')
             prnt('    1, sizeof(%s),' % cname)
             prnt('    offsetof(struct _cffi_aligncheck, y),')
@@ -256,7 +266,7 @@
             raise ffiplatform.VerificationError(
                 "incompatible layout for %s" % cname)
         elif layout == 0:
-            assert not tp.partial
+            assert isinstance(tp, model.UnionType) or not tp.partial
         else:
             totalsize = function(1)
             totalalignment = function(2)
diff --git a/doc/source/index.rst b/doc/source/index.rst
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -505,6 +505,9 @@
 example.  You may work around it, but mixing CFFI with ``Python.h`` is
 not recommended.
 
+.. versionadded:: 0.4
+   Unions used to crash ``verify()``.  Fixed.
+
 
 Working with pointers, structures and arrays
 --------------------------------------------
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -983,3 +983,8 @@
         struct foo_s { int a, padding; char c, d, b; };
     """)
     assert ffi.sizeof("struct foo_s") == 3 * ffi.sizeof("int")
+
+def test_ffi_union():
+    ffi = FFI()
+    ffi.cdef("union foo_u { char x; long *z; };")
+    ffi.verify("union foo_u { char x; int y; long *z; };")


More information about the pypy-commit mailing list