From ca585be25e2df6291ac6fd747c1152187d2669d6 Mon Sep 17 00:00:00 2001 From: alex-xnor Date: Wed, 16 Oct 2019 11:48:51 -0700 Subject: [PATCH] Make sure not to emit duplicate typedefs for fused nodes (GH-3112) --- Cython/Compiler/FusedNode.py | 14 +++++---- tests/compile/fused_redeclare_T3111.pyx | 39 +++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 tests/compile/fused_redeclare_T3111.pyx diff --git a/Cython/Compiler/FusedNode.py b/Cython/Compiler/FusedNode.py index 011290e954a..87a9ae2b343 100644 --- a/Cython/Compiler/FusedNode.py +++ b/Cython/Compiler/FusedNode.py @@ -507,20 +507,22 @@ def _buffer_declarations(self, pyx_code, decl_code, all_buffer_types, pythran_ty ndarray = __Pyx_ImportNumPyArrayTypeIfAvailable() """) + seen_typedefs = set() seen_int_dtypes = set() for buffer_type in all_buffer_types: dtype = buffer_type.dtype + dtype_name = self._dtype_name(dtype) if dtype.is_typedef: - #decl_code.putln("ctypedef %s %s" % (dtype.resolve(), - # self._dtype_name(dtype))) - decl_code.putln('ctypedef %s %s "%s"' % (dtype.resolve(), - self._dtype_name(dtype), - dtype.empty_declaration_code())) + if dtype_name not in seen_typedefs: + seen_typedefs.add(dtype_name) + decl_code.putln( + 'ctypedef %s %s "%s"' % (dtype.resolve(), dtype_name, + dtype.empty_declaration_code())) if buffer_type.dtype.is_int: if str(dtype) not in seen_int_dtypes: seen_int_dtypes.add(str(dtype)) - pyx_code.context.update(dtype_name=self._dtype_name(dtype), + pyx_code.context.update(dtype_name=dtype_name, dtype_type=self._dtype_type(dtype)) pyx_code.local_variable_declarations.put_chunk( u""" diff --git a/tests/compile/fused_redeclare_T3111.pyx b/tests/compile/fused_redeclare_T3111.pyx new file mode 100644 index 00000000000..3dfed9f38b0 --- /dev/null +++ b/tests/compile/fused_redeclare_T3111.pyx @@ -0,0 +1,39 @@ +# ticket: 3111 +# mode: compile +# tag: warnings + +ctypedef unsigned char npy_uint8 +ctypedef unsigned short npy_uint16 + + +ctypedef fused dtype_t: + npy_uint8 + +ctypedef fused dtype_t_out: + npy_uint8 + npy_uint16 + + +def foo(dtype_t[:] a, dtype_t_out[:, :] b): + pass + + +# The primary thing we're trying to test here is the _absence_ of the warning +# "__pyxutil:16:4: '___pyx_npy_uint8' redeclared". The remaining warnings are +# unrelated to this test. +_WARNINGS = """ +22:10: 'cpdef_method' redeclared +33:10: 'cpdef_cname_method' redeclared +446:72: Argument evaluation order in C function call is undefined and may not be as expected +446:72: Argument evaluation order in C function call is undefined and may not be as expected +749:34: Argument evaluation order in C function call is undefined and may not be as expected +749:34: Argument evaluation order in C function call is undefined and may not be as expected +943:27: Ambiguous exception value, same as default return value: 0 +943:27: Ambiguous exception value, same as default return value: 0 +974:29: Ambiguous exception value, same as default return value: 0 +974:29: Ambiguous exception value, same as default return value: 0 +1002:46: Ambiguous exception value, same as default return value: 0 +1002:46: Ambiguous exception value, same as default return value: 0 +1092:29: Ambiguous exception value, same as default return value: 0 +1092:29: Ambiguous exception value, same as default return value: 0 +"""