[pypy-commit] cffi default: Two tests from the mailing list, and fixes: bogus "const" detection,

arigo noreply at buildbot.pypy.org
Sat Sep 14 09:54:43 CEST 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r1348:e2728981fbaa
Date: 2013-09-14 09:54 +0200
http://bitbucket.org/cffi/cffi/changeset/e2728981fbaa/

Log:	Two tests from the mailing list, and fixes: bogus "const" detection,
	and global array variables should never be "const".

diff --git a/cffi/cparser.py b/cffi/cparser.py
--- a/cffi/cparser.py
+++ b/cffi/cparser.py
@@ -217,7 +217,7 @@
             #
             if decl.name:
                 tp = self._get_type(node, partial_length_ok=True)
-                if self._is_constant_declaration(node):
+                if self._is_constant_globalvar(node):
                     self._declare('constant ' + decl.name, tp)
                 else:
                     self._declare('variable ' + decl.name, tp)
@@ -372,14 +372,11 @@
         result = self._get_type(typenode.type)
         return model.RawFunctionType(tuple(args), result, ellipsis)
 
-    def _is_constant_declaration(self, typenode, const=False):
-        if isinstance(typenode, pycparser.c_ast.ArrayDecl):
-            return self._is_constant_declaration(typenode.type)
+    def _is_constant_globalvar(self, typenode):
         if isinstance(typenode, pycparser.c_ast.PtrDecl):
-            const = 'const' in typenode.quals
-            return self._is_constant_declaration(typenode.type, const)
+            return 'const' in typenode.quals
         if isinstance(typenode, pycparser.c_ast.TypeDecl):
-            return const or 'const' in typenode.quals
+            return 'const' in typenode.quals
         return False
 
     def _get_struct_union_enum_type(self, kind, type, name=None, nested=False):
diff --git a/cffi/model.py b/cffi/model.py
--- a/cffi/model.py
+++ b/cffi/model.py
@@ -192,10 +192,6 @@
     _base_pattern       = " const *&"
     _base_pattern_array = "(const *&)"
 
-    def build_backend_type(self, ffi, finishlist):
-        BPtr = PointerType(self.totype).get_cached_btype(ffi, finishlist)
-        return BPtr
-
 const_voidp_type = ConstPointerType(void_type)
 
 
diff --git a/testing/test_parsing.py b/testing/test_parsing.py
--- a/testing/test_parsing.py
+++ b/testing/test_parsing.py
@@ -255,3 +255,27 @@
         py.test.skip("Only for Windows")
     ffi = FFI()
     ffi.cdef("void f(WPARAM);")
+
+def test__is_constant_globalvar():
+    from cffi.cparser import Parser, _get_parser
+    for input, expected_output in [
+        ("int a;",          False),
+        ("const int a;",    True),
+        ("int *a;",         False),
+        ("const int *a;",   False),
+        ("int const *a;",   False),
+        ("int *const a;",   True),
+        ("int a[5];",       False),
+        ("const int a[5];", False),
+        ("int *a[5];",      False),
+        ("const int *a[5];", False),
+        ("int const *a[5];", False),
+        ("int *const a[5];", False),
+        ("int a[5][6];",       False),
+        ("const int a[5][6];", False),
+        ]:
+        p = Parser()
+        ast = _get_parser().parse(input)
+        decl = ast.children()[0][1]
+        node = decl.type
+        assert p._is_constant_globalvar(node) == expected_output
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -1644,3 +1644,16 @@
     m = lib.foo(s[0])
     assert m == -1234
     assert repr(ffi.typeof(lib.foo)) == "<ctype 'int(*)(struct s)'>"
+
+def test_bug_const_char_ptr_array_1():
+    ffi = FFI()
+    ffi.cdef("""const char *a[...];""")
+    lib = ffi.verify("""const char *a[5];""")
+    assert repr(ffi.typeof(lib.a)) == "<ctype 'char * *'>"
+
+def test_bug_const_char_ptr_array_2():
+    from cffi import FFI     # ignore warnings
+    ffi = FFI()
+    ffi.cdef("""const int a[];""")
+    lib = ffi.verify("""const int a[5];""")
+    assert repr(ffi.typeof(lib.a)) == "<ctype 'int *'>"


More information about the pypy-commit mailing list