summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2015-02-23 21:57:32 +0100
committerStefan Behnel <stefan_ml@behnel.de>2015-02-23 21:57:32 +0100
commit9a708007c258b2364e7c409b0d1ea1bf53289b45 (patch)
tree21b7e6801df743558d2c20204eb9fed4f3dd2443
parent65840df620b3c5a3d9446daa95b81c17f19d40f2 (diff)
downloadcython-9a708007c258b2364e7c409b0d1ea1bf53289b45.tar.gz
fix comparison of function signatures that use C++ exception mappings
-rw-r--r--CHANGES.rst3
-rw-r--r--Cython/Compiler/PyrexTypes.py28
-rw-r--r--tests/run/cpp_exception_declaration_compatibility.srctree38
3 files changed, 63 insertions, 6 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index f48eec02e..b25c5f9a9 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -16,6 +16,9 @@ Bugs fixed
* Comparisons of (inferred) ctuples failed to compile.
+* C++ exception declarations with mapping functions could fail to compile when
+ pre-declared in .pxd files.
+
* C compilation could fail in pypy3.
diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py
index 393d7ab9f..2543f73d7 100644
--- a/Cython/Compiler/PyrexTypes.py
+++ b/Cython/Compiler/PyrexTypes.py
@@ -2572,10 +2572,26 @@ class CFuncType(CType):
return 0
if not self.same_calling_convention_as(other_type):
return 0
- if self.exception_value != other_type.exception_value:
- return 0
if self.exception_check != other_type.exception_check:
return 0
+ if not self._same_exception_value(other_type.exception_value):
+ return 0
+ return 1
+
+ def _same_exception_value(self, other_exc_value):
+ if self.exception_value == other_exc_value:
+ return 1
+ if self.exception_check != '+':
+ return 0
+ if not self.exception_value or not other_exc_value:
+ return 0
+ if self.exception_value.type != other_exc_value.type:
+ return 0
+ if self.exception_value.entry and other_exc_value.entry:
+ if self.exception_value.entry.cname != other_exc_value.entry.cname:
+ return 0
+ if self.exception_value.name != other_exc_value.name:
+ return 0
return 1
def compatible_signature_with(self, other_type, as_cmethod = 0):
@@ -2610,11 +2626,11 @@ class CFuncType(CType):
return 0
if self.nogil != other_type.nogil:
return 0
- if self.exception_value != other_type.exception_value:
- return 0
if not self.exception_check and other_type.exception_check:
# a redundant exception check doesn't make functions incompatible, but a missing one does
return 0
+ if not self._same_exception_value(other_type.exception_value):
+ return 0
self.original_sig = other_type.original_sig or other_type
return 1
@@ -2641,11 +2657,11 @@ class CFuncType(CType):
return 0
if not self.return_type.subtype_of_resolved_type(other_type.return_type):
return 0
- if self.exception_value != other_type.exception_value:
- return 0
if not self.exception_check and other_type.exception_check:
# a redundant exception check doesn't make functions incompatible, but a missing one does
return 0
+ if not self._same_exception_value(other_type.exception_value):
+ return 0
return 1
def same_calling_convention_as(self, other):
diff --git a/tests/run/cpp_exception_declaration_compatibility.srctree b/tests/run/cpp_exception_declaration_compatibility.srctree
new file mode 100644
index 000000000..775761c23
--- /dev/null
+++ b/tests/run/cpp_exception_declaration_compatibility.srctree
@@ -0,0 +1,38 @@
+# tag: cpp
+
+"""
+PYTHON setup.py build_ext -i
+PYTHON test.py
+"""
+
+############### setup.py ###################
+from distutils.core import setup
+from Cython.Build import cythonize
+
+setup(
+ name="cython_test",
+ ext_modules=cythonize('*.pyx', language="c++")
+)
+
+
+############### test.py ###################
+
+from cpp_exc import TestClass
+
+TestClass().test_func()
+
+
+############### cpp_exc.pxd ###################
+
+cdef inline void handle_exception():
+ pass
+
+cdef class TestClass:
+ cpdef test_func(self) except +handle_exception
+
+
+############### cpp_exc.pyx ###################
+
+cdef class TestClass:
+ cpdef test_func(self) except +handle_exception:
+ print('test')