Commit bf630e08 authored by Stefan Behnel's avatar Stefan Behnel

fix vtable type casting in Py3 to support strict aliasing

parent 1e0af779
...@@ -1967,13 +1967,27 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1967,13 +1967,27 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
type.vtable_cname, type.vtable_cname,
Naming.obj_base_cname, Naming.obj_base_cname,
type.base_type.vtabptr_cname)) type.base_type.vtabptr_cname))
for meth_entry in type.scope.cfunc_entries:
if meth_entry.func_cname: c_method_entries = [
code.putln( entry for entry in type.scope.cfunc_entries
"*(void(**)(void))&%s.%s = (void(*)(void))%s;" % ( if entry.func_cname ]
type.vtable_cname, code.putln('#if PY_MAJOR_VERSION >= 3')
meth_entry.cname, for meth_entry in c_method_entries:
meth_entry.func_cname)) 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): def generate_typeptr_assignment_code(self, entry, code):
# Generate code to initialise the typeptr of an extension # Generate code to initialise the typeptr of an extension
......
...@@ -874,7 +874,8 @@ class CFuncType(CType): ...@@ -874,7 +874,8 @@ class CFuncType(CType):
and not (self.nogil and not other_type.nogil) and not (self.nogil and not other_type.nogil)
def declaration_code(self, entity_code, 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 = [] arg_decl_list = []
for arg in self.args[:len(self.args)-self.optional_arg_count]: for arg in self.args[:len(self.args)-self.optional_arg_count]:
arg_decl_list.append( arg_decl_list.append(
...@@ -900,10 +901,13 @@ class CFuncType(CType): ...@@ -900,10 +901,13 @@ class CFuncType(CType):
" except *" # ignored " except *" # ignored
if self.nogil: if self.nogil:
trailer += " nogil" trailer += " nogil"
cc = self.calling_convention_prefix() if not with_calling_convention:
if (not entity_code and cc) or entity_code.startswith("*"): cc = ''
entity_code = "(%s%s)" % (cc, entity_code) else:
cc = "" 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( return self.return_type.declaration_code(
"%s%s(%s)%s" % (cc, entity_code, arg_decl_code, trailer), "%s%s(%s)%s" % (cc, entity_code, arg_decl_code, trailer),
for_display, dll_linkage, pyrex) for_display, dll_linkage, pyrex)
...@@ -916,6 +920,10 @@ class CFuncType(CType): ...@@ -916,6 +920,10 @@ class CFuncType(CType):
s = self.declaration_code("") s = self.declaration_code("")
return s return s
def signature_cast_string(self):
s = self.declaration_code("(*)", with_calling_convention=False)
return '(%s)' % s
class CFuncTypeArg: class CFuncTypeArg:
# name string # name string
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment