Commit 34a5e359 authored by Xavier Thompson's avatar Xavier Thompson

Disallow method overloading on cypclass qualifiers

parent 48a1e3f9
......@@ -3219,6 +3219,8 @@ class CFuncType(CType):
return 0
if self.has_varargs != other_type.has_varargs:
return 0
if self.self_qualifier != other_type.self_qualifier:
return 0
self_minargs = len(self.args) - self.optional_arg_count
if self_minargs > len(other_type.args):
return 0
......@@ -3255,6 +3257,8 @@ class CFuncType(CType):
return 0
if self.has_varargs != other_type.has_varargs:
return 0
if self.self_qualifier != other_type.self_qualifier:
return 0
return 1
def compatible_signature_with(self, other_type, as_cmethod = 0, skip_args=0, skip_return=0):
......@@ -3313,6 +3317,29 @@ class CFuncType(CType):
return 0
if self.has_varargs != other_type.has_varargs:
return 0
if self.self_qualifier != other_type.self_qualifier:
return 0
if self.optional_arg_count != other_type.optional_arg_count:
return 0
return 1
def same_args_without_qualifiers_with(self, other_type, as_cmethod = 0):
return self.same_args_without_qualifiers_with_resolved_type(other_type.resolve(), as_cmethod)
def same_args_without_qualifiers_with_resolved_type(self, other_type, as_cmethod = 0):
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 same_without_qualifier(self.args[i].type, other_type.args[i].type):
if not self.args[i].type.same_as(other_type.args[i].type):
return 0
if self.has_varargs != other_type.has_varargs:
return 0
if self.optional_arg_count != other_type.optional_arg_count:
return 0
return 1
......@@ -3334,6 +3361,8 @@ class CFuncType(CType):
return 0
if self.has_varargs != other_type.has_varargs:
return 0
if self.self_qualifier != other_type.self_qualifier:
return 0
if self.optional_arg_count != other_type.optional_arg_count:
return 0
return 1
......@@ -3357,6 +3386,8 @@ class CFuncType(CType):
return 0
if self.has_varargs != other_type.has_varargs:
return 0
if self.self_qualifier != other_type.self_qualifier:
return 0
if self.optional_arg_count != other_type.optional_arg_count:
return 0
return 1
......@@ -3396,7 +3427,7 @@ class CFuncType(CType):
def same_as_resolved_type(self, other_type, as_cmethod=False):
return self.same_c_signature_as_resolved_type(other_type, as_cmethod=as_cmethod) \
and self.nogil == other_type.nogil
and self.nogil == other_type.nogil and self.self_qualifier == other_type.self_qualifier
def pointer_assignable_from_resolved_type(self, rhs_type):
# Accept compatible exception/nogil declarations for the RHS.
......@@ -5913,6 +5944,15 @@ def ptr_to_same_without_cv(type1, type2):
return same_type(type1, type2)
return 0
def same_without_qualifier(type1, type2):
if type1.is_cyp_class and type2.is_cyp_class:
if type1.is_qualified_cyp_class:
type1 = type1.qual_base_type
if type2.is_qualified_cyp_class:
type2 = type2.qual_base_type
return same_type(type1, type2)
return 0
def typecast(to_type, from_type, expr_code):
# Return expr_code cast to a C type which can be
# assigned to to_type, assuming its existing C type
......
......@@ -543,7 +543,13 @@ class Scope(object):
for index, alt_entry in enumerate(old_entry.all_alternatives()):
alt_type = alt_entry.type
if type.compatible_arguments_with(alt_type):
if type.self_qualifier != alt_type.self_qualifier:
error(pos, "Cannot overload on 'self' qualifier")
if alt_entry.pos is not None:
error(alt_entry.pos, "Conflicting method is defined here")
break
elif type.compatible_arguments_with(alt_type):
cpp_override_allowed = False
# allow default constructor or __alloc__ to be redeclared by user
......@@ -575,13 +581,13 @@ class Scope(object):
alt_type.declaration_code(name, for_display = 1).strip()))
)
if alt_entry.pos is not None:
error(alt_entry.pos, "Conflicting method is defined here")
error(alt_entry.pos, "Conflicting method is defined here")
# the return type must be covariant
elif not type.return_type.subtype_of_resolved_type(alt_type.return_type):
error(pos, "Cypclass method overrides another with incompatible return type")
if alt_entry.pos is not None:
error(alt_entry.pos, "Conflicting method is defined here")
error(alt_entry.pos, "Conflicting method is defined here")
previous_alternative_indices.append(index)
cpp_override_allowed = True
......@@ -594,6 +600,13 @@ class Scope(object):
elif type.same_ptr_args_without_cv_with(alt_type):
error(pos, "Cypclass method const-overloads another method: not supported yet")
# Disallow qualifier overloads
elif type.same_args_without_qualifiers_with(alt_type):
error(pos, "Cannot overload on cypclass qualifiers")
if alt_entry.pos is not None:
error(alt_entry.pos, "Conflicting method is defined here")
break
# if an overloaded alternative has narrower argument types than another, then the method
# actually called will depend on the static type of the arguments
# we actually also disallow methods where each argument is either narrower or larger
......@@ -601,6 +614,7 @@ class Scope(object):
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")
break
# normal cpp case
else:
......
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