FunctionDefinition.resolveVirtual(): Skip unimplemented functions when lookup happens via super

This commit is contained in:
Kamil Śliwak
2021-06-02 16:16:15 +02:00
parent 67e87147b4
commit d96cc3469a
11 changed files with 140 additions and 4 deletions
+10 -2
View File
@@ -397,6 +397,7 @@ FunctionDefinition const& FunctionDefinition::resolveVirtual(
) const
{
solAssert(!isConstructor(), "");
// If we are not doing super-lookup and the function is not virtual, we can stop here.
if (_searchStart == nullptr && !virtualSemantics())
return *this;
@@ -407,19 +408,26 @@ FunctionDefinition const& FunctionDefinition::resolveVirtual(
FunctionType const* functionType = TypeProvider::function(*this)->asExternallyCallableFunction(false);
bool foundSearchStart = (_searchStart == nullptr);
for (ContractDefinition const* c: _mostDerivedContract.annotation().linearizedBaseContracts)
{
if (_searchStart != nullptr && c != _searchStart)
if (!foundSearchStart && c != _searchStart)
continue;
_searchStart = nullptr;
else
foundSearchStart = true;
for (FunctionDefinition const* function: c->definedFunctions())
if (
function->name() == name() &&
!function->isConstructor() &&
// With super lookup analysis guarantees that there is an implemented function in the chain.
// With virtual lookup there are valid cases where returning an unimplemented one is fine.
(function->isImplemented() || _searchStart == nullptr) &&
FunctionType(*function).asExternallyCallableFunction(false)->hasEqualParameterTypes(*functionType)
)
return *function;
}
solAssert(false, "Virtual function " + name() + " not found.");
return *this; // not reached
}