Author: Armin Rigo <[email protected]>
Branch:
Changeset: r2728:a50293aa9bd1
Date: 2016-07-31 15:07 +0200
http://bitbucket.org/cffi/cffi/changeset/a50293aa9bd1/
Log: Test and fix: refuse to 'recompile' a cdef that declares a struct
with an opaque struct as a field
diff --git a/cffi/recompiler.py b/cffi/recompiler.py
--- a/cffi/recompiler.py
+++ b/cffi/recompiler.py
@@ -862,6 +862,8 @@
enumfields = list(tp.enumfields())
for fldname, fldtype, fbitsize, fqual in enumfields:
fldtype = self._field_type(tp, fldname, fldtype)
+ self._check_not_opaque(fldtype,
+ "field '%s.%s'" % (tp.name, fldname))
# cname is None for _add_missing_struct_unions() only
op = OP_NOOP
if fbitsize >= 0:
@@ -911,6 +913,13 @@
first_field_index, c_fields))
self._seen_struct_unions.add(tp)
+ def _check_not_opaque(self, tp, location):
+ while isinstance(tp, model.ArrayType):
+ tp = tp.item
+ if isinstance(tp, model.StructOrUnion) and tp.fldtypes is None:
+ raise TypeError(
+ "%s is of an opaque type (not declared in cdef())" % location)
+
def _add_missing_struct_unions(self):
# not very nice, but some struct declarations might be missing
# because they don't have any known C name. Check that they are
diff --git a/testing/cffi1/test_recompiler.py b/testing/cffi1/test_recompiler.py
--- a/testing/cffi1/test_recompiler.py
+++ b/testing/cffi1/test_recompiler.py
@@ -1918,3 +1918,35 @@
ffi.cdef("bool f(void);")
lib = verify(ffi, "test_bool_in_cpp", "char f(void) { return 2; }")
assert lib.f() == 1
+
+def test_struct_field_opaque():
+ ffi = FFI()
+ ffi.cdef("struct a { struct b b; };")
+ e = py.test.raises(TypeError, verify,
+ ffi, "test_struct_field_opaque", "?")
+ assert str(e.value) == ("struct a: field 'a.b' is of an opaque"
+ " type (not declared in cdef())")
+ ffi = FFI()
+ ffi.cdef("struct a { struct b b[2]; };")
+ e = py.test.raises(TypeError, verify,
+ ffi, "test_struct_field_opaque", "?")
+ assert str(e.value) == ("struct a: field 'a.b' is of an opaque"
+ " type (not declared in cdef())")
+ ffi = FFI()
+ ffi.cdef("struct a { struct b b[]; };")
+ e = py.test.raises(TypeError, verify,
+ ffi, "test_struct_field_opaque", "?")
+ assert str(e.value) == ("struct a: field 'a.b' is of an opaque"
+ " type (not declared in cdef())")
+
+def test_function_arg_opaque():
+ py.test.skip("can currently declare a function with an opaque struct "
+ "as argument, but AFAICT it's impossible to call it later")
+
+def test_function_returns_opaque():
+ ffi = FFI()
+ ffi.cdef("struct a foo(int);")
+ e = py.test.raises(TypeError, verify,
+ ffi, "test_function_returns_opaque", "?")
+ assert str(e.value) == ("function foo: 'struct a' is used as result type,"
+ " but is opaque")
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit