Commit 77032493 authored by Xavier Thompson's avatar Xavier Thompson

Disallow cypclass method overloading with narrower or larger arguments

parent 5543e04b
......@@ -3046,6 +3046,32 @@ class CFuncType(CType):
return 0
return 1
def narrower_or_larger_arguments_than(self, other_type, as_cmethod = 0):
return self.narrower_or_larger_arguments_than_resolved_type(other_type.resolve(), as_cmethod)
def narrower_or_larger_arguments_than_resolved_type(self, other_type, as_cmethod):
if other_type is error_type:
return 1
if not other_type.is_cfunction:
return 0
nargs = len(self.args)
if nargs != len(other_type.args):
return 0
for i in range(as_cmethod, nargs):
if not self.args[i].type.subtype_of_resolved_type(other_type.args[i].type):
if not other_type.args[i].type.subtype_of_resolved_type(self.args[i].type):
return 0
else:
other_type.args[i].needs_type_test = True
else:
self.args[i].needs_type_test = other_type.args[i].needs_type_test \
or not self.args[i].type.same_as(other_type.args[i].type)
if self.has_varargs != other_type.has_varargs:
return 0
if self.optional_arg_count != other_type.optional_arg_count:
return 0
return 1
def narrower_arguments_than(self, other_type, as_cmethod = 0):
return self.narrower_arguments_than_resolved_type(other_type.resolve(), as_cmethod)
......
......@@ -571,7 +571,7 @@ class Scope(object):
alt_declarator_str = alt_type.declarator_code(name, for_display = 1).strip()
new_declarator_str = type.declarator_code(name, for_display = 1).strip()
if new_declarator_str != alt_declarator_str:
error(pos, ("Fallacious override:\n"
error(pos, ("False override:\n"
"Cypclass method\n"
">> %s\n"
"has compatible arguments with inherited method\n"
......@@ -598,8 +598,9 @@ class Scope(object):
# if an overloaded alternative has narrower argument types than another, then the method
# actually called will depend on the static type of the arguments
elif type.narrower_arguments_than(alt_type) or alt_type.narrower_arguments_than(type):
error(pos, "Cypclass overloaded method with narrower arguments")
# we actually also disallow methods where each argument is either narrower or larger
elif type.narrower_or_larger_arguments_than(alt_type):
error(pos, "Cypclass overloaded method with narrower or larger arguments")
if alt_entry.pos is not None:
error(alt_entry.pos, "Conflicting method is defined here")
......
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