@@ -313,7 +313,7 @@ Token OverrideProxy::functionKind() const
313313 }, m_item);
314314}
315315
316- FunctionType const * OverrideProxy::functionType () const
316+ FunctionType const * OverrideProxy::externalFunctionType () const
317317{
318318 return std::visit (GenericVisitor{
319319 [&](FunctionDefinition const * _item) { return FunctionType (*_item).asExternallyCallableFunction (false ); },
@@ -322,6 +322,15 @@ FunctionType const* OverrideProxy::functionType() const
322322 }, m_item);
323323}
324324
325+ FunctionType const * OverrideProxy::specificFunctionType () const
326+ {
327+ return std::visit (GenericVisitor{
328+ [&](FunctionDefinition const * _item) { return TypeProvider::function (*_item); },
329+ [&](VariableDeclaration const *) -> FunctionType const * { solAssert (false , " Requested specifig function type of variable." ); return nullptr ; },
330+ [&](ModifierDefinition const *) -> FunctionType const * { solAssert (false , " Requested specific function type of modifier." ); return nullptr ; }
331+ }, m_item);
332+ }
333+
325334ModifierType const * OverrideProxy::modifierType () const
326335{
327336 return std::visit (GenericVisitor{
@@ -413,7 +422,7 @@ OverrideProxy::OverrideComparator const& OverrideProxy::overrideComparator() con
413422 [&](FunctionDefinition const * _function)
414423 {
415424 vector<string> paramTypes;
416- for (Type const * t: functionType ()->parameterTypes ())
425+ for (Type const * t: externalFunctionType ()->parameterTypes ())
417426 paramTypes.emplace_back (t->richIdentifier ());
418427 return OverrideComparator{
419428 _function->name (),
@@ -424,7 +433,7 @@ OverrideProxy::OverrideComparator const& OverrideProxy::overrideComparator() con
424433 [&](VariableDeclaration const * _var)
425434 {
426435 vector<string> paramTypes;
427- for (Type const * t: functionType ()->parameterTypes ())
436+ for (Type const * t: externalFunctionType ()->parameterTypes ())
428437 paramTypes.emplace_back (t->richIdentifier ());
429438 return OverrideComparator{
430439 _var->name (),
@@ -589,21 +598,54 @@ void OverrideChecker::checkOverride(OverrideProxy const& _overriding, OverridePr
589598
590599 if (_super.isFunction ())
591600 {
592- FunctionType const * functionType = _overriding.functionType ();
593- FunctionType const * superType = _super.functionType ();
601+ FunctionType const * functionType = _overriding.externalFunctionType ();
602+ FunctionType const * superType = _super.externalFunctionType ();
594603
604+ bool returnTypesDifferAlready = false ;
595605 if (_overriding.functionKind () != Token::Fallback)
596606 {
597607 solAssert (functionType->hasEqualParameterTypes (*superType), " Override doesn't have equal parameters!" );
598608
599609 if (!functionType->hasEqualReturnTypes (*superType))
610+ {
611+ returnTypesDifferAlready = true ;
600612 overrideError (
601613 _overriding,
602614 _super,
603615 4822_error,
604616 " Overriding " + _overriding.astNodeName () + " return types differ." ,
605617 " Overridden " + _overriding.astNodeName () + " is here:"
606618 );
619+ }
620+ }
621+
622+ // The override proxy considers calldata and memory the same data location.
623+ // Here we do a more specific check:
624+ // Data locations of parameters and return variables have to match
625+ // unless we have a public function overriding an external one.
626+ if (
627+ _overriding.isFunction () &&
628+ !returnTypesDifferAlready &&
629+ _super.visibility () != Visibility::External &&
630+ _overriding.functionKind () != Token::Fallback
631+ )
632+ {
633+ if (!_overriding.specificFunctionType ()->hasEqualParameterTypes (*_super.specificFunctionType ()))
634+ overrideError (
635+ _overriding,
636+ _super,
637+ 7723_error,
638+ " Data locations of parameters have to be the same when overriding, but they differ." ,
639+ " Overridden " + _overriding.astNodeName () + " is here:"
640+ );
641+ if (!_overriding.specificFunctionType ()->hasEqualReturnTypes (*_super.specificFunctionType ()))
642+ overrideError (
643+ _overriding,
644+ _super,
645+ 1443_error,
646+ " Data locations of return variables have to be the same when overriding, but they differ." ,
647+ " Overridden " + _overriding.astNodeName () + " is here:"
648+ );
607649 }
608650
609651 // Stricter mutability is always okay except when super is Payable
0 commit comments