From bf630e0829534be161ec7b11edb045e78fe6a776 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Sat, 28 Feb 2009 08:43:22 +0100 Subject: [PATCH] fix vtable type casting in Py3 to support strict aliasing --- Cython/Compiler/ModuleNode.py | 28 +++++++++++++++++++++------- Cython/Compiler/PyrexTypes.py | 18 +++++++++++++----- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index fa1695eb..bee9a424 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -1967,13 +1967,27 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): type.vtable_cname, Naming.obj_base_cname, type.base_type.vtabptr_cname)) - for meth_entry in type.scope.cfunc_entries: - if meth_entry.func_cname: - code.putln( - "*(void(**)(void))&%s.%s = (void(*)(void))%s;" % ( - type.vtable_cname, - meth_entry.cname, - meth_entry.func_cname)) + + c_method_entries = [ + entry for entry in type.scope.cfunc_entries + if entry.func_cname ] + code.putln('#if PY_MAJOR_VERSION >= 3') + for meth_entry in c_method_entries: + cast = meth_entry.type.signature_cast_string() + code.putln( + "%s.%s = %s%s;" % ( + type.vtable_cname, + meth_entry.cname, + cast, + meth_entry.func_cname)) + code.putln('#else') + for meth_entry in c_method_entries: + code.putln( + "*(void(**)(void))&%s.%s = (void(*)(void))%s;" % ( + type.vtable_cname, + meth_entry.cname, + meth_entry.func_cname)) + code.putln('#endif') def generate_typeptr_assignment_code(self, entry, code): # Generate code to initialise the typeptr of an extension diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py index fe8b14e1..aeea3c50 100644 --- a/Cython/Compiler/PyrexTypes.py +++ b/Cython/Compiler/PyrexTypes.py @@ -874,7 +874,8 @@ class CFuncType(CType): and not (self.nogil and not other_type.nogil) def declaration_code(self, entity_code, - for_display = 0, dll_linkage = None, pyrex = 0): + for_display = 0, dll_linkage = None, pyrex = 0, + with_calling_convention = 1): arg_decl_list = [] for arg in self.args[:len(self.args)-self.optional_arg_count]: arg_decl_list.append( @@ -900,10 +901,13 @@ class CFuncType(CType): " except *" # ignored if self.nogil: trailer += " nogil" - cc = self.calling_convention_prefix() - if (not entity_code and cc) or entity_code.startswith("*"): - entity_code = "(%s%s)" % (cc, entity_code) - cc = "" + if not with_calling_convention: + cc = '' + else: + cc = self.calling_convention_prefix() + if (not entity_code and cc) or entity_code.startswith("*"): + entity_code = "(%s%s)" % (cc, entity_code) + cc = "" return self.return_type.declaration_code( "%s%s(%s)%s" % (cc, entity_code, arg_decl_code, trailer), for_display, dll_linkage, pyrex) @@ -916,6 +920,10 @@ class CFuncType(CType): s = self.declaration_code("") return s + def signature_cast_string(self): + s = self.declaration_code("(*)", with_calling_convention=False) + return '(%s)' % s + class CFuncTypeArg: # name string -- 2.26.2