mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Move external type clash check.
This commit is contained in:
parent
4f4f623273
commit
6d1644e55c
@ -42,6 +42,7 @@ bool ContractLevelChecker::check(ContractDefinition const& _contract)
|
||||
checkBaseConstructorArguments(_contract);
|
||||
checkConstructor(_contract);
|
||||
checkFallbackFunction(_contract);
|
||||
checkExternalTypeClashes(_contract);
|
||||
|
||||
return Error::containsOnlyWarnings(m_errorReporter.errors());
|
||||
}
|
||||
@ -383,3 +384,39 @@ void ContractLevelChecker::checkFallbackFunction(ContractDefinition const& _cont
|
||||
if (fallback->visibility() != FunctionDefinition::Visibility::External)
|
||||
m_errorReporter.typeError(fallback->location(), "Fallback function must be defined as \"external\".");
|
||||
}
|
||||
|
||||
void ContractLevelChecker::checkExternalTypeClashes(ContractDefinition const& _contract)
|
||||
{
|
||||
map<string, vector<pair<Declaration const*, FunctionTypePointer>>> externalDeclarations;
|
||||
for (ContractDefinition const* contract: _contract.annotation().linearizedBaseContracts)
|
||||
{
|
||||
for (FunctionDefinition const* f: contract->definedFunctions())
|
||||
if (f->isPartOfExternalInterface())
|
||||
{
|
||||
auto functionType = make_shared<FunctionType>(*f);
|
||||
// under non error circumstances this should be true
|
||||
if (functionType->interfaceFunctionType())
|
||||
externalDeclarations[functionType->externalSignature()].push_back(
|
||||
make_pair(f, functionType->asCallableFunction(false))
|
||||
);
|
||||
}
|
||||
for (VariableDeclaration const* v: contract->stateVariables())
|
||||
if (v->isPartOfExternalInterface())
|
||||
{
|
||||
auto functionType = make_shared<FunctionType>(*v);
|
||||
// under non error circumstances this should be true
|
||||
if (functionType->interfaceFunctionType())
|
||||
externalDeclarations[functionType->externalSignature()].push_back(
|
||||
make_pair(v, functionType->asCallableFunction(false))
|
||||
);
|
||||
}
|
||||
}
|
||||
for (auto const& it: externalDeclarations)
|
||||
for (size_t i = 0; i < it.second.size(); ++i)
|
||||
for (size_t j = i + 1; j < it.second.size(); ++j)
|
||||
if (!it.second[i].second->hasEqualParameterTypes(*it.second[j].second))
|
||||
m_errorReporter.typeError(
|
||||
it.second[j].first->location(),
|
||||
"Function overload clash during conversion to external types for arguments."
|
||||
);
|
||||
}
|
||||
|
@ -72,6 +72,9 @@ private:
|
||||
);
|
||||
void checkConstructor(ContractDefinition const& _contract);
|
||||
void checkFallbackFunction(ContractDefinition const& _contract);
|
||||
/// Checks that different functions with external visibility end up having different
|
||||
/// external argument types (i.e. different signature).
|
||||
void checkExternalTypeClashes(ContractDefinition const& _contract);
|
||||
|
||||
langutil::ErrorReporter& m_errorReporter;
|
||||
};
|
||||
|
@ -93,7 +93,6 @@ bool TypeChecker::visit(ContractDefinition const& _contract)
|
||||
for (auto const& n: _contract.subNodes())
|
||||
n->accept(*this);
|
||||
|
||||
checkContractExternalTypeClashes(_contract);
|
||||
// check for hash collisions in function signatures
|
||||
set<FixedHash<4>> hashes;
|
||||
for (auto const& it: _contract.interfaceFunctionList())
|
||||
@ -113,42 +112,6 @@ bool TypeChecker::visit(ContractDefinition const& _contract)
|
||||
return false;
|
||||
}
|
||||
|
||||
void TypeChecker::checkContractExternalTypeClashes(ContractDefinition const& _contract)
|
||||
{
|
||||
map<string, vector<pair<Declaration const*, FunctionTypePointer>>> externalDeclarations;
|
||||
for (ContractDefinition const* contract: _contract.annotation().linearizedBaseContracts)
|
||||
{
|
||||
for (FunctionDefinition const* f: contract->definedFunctions())
|
||||
if (f->isPartOfExternalInterface())
|
||||
{
|
||||
auto functionType = make_shared<FunctionType>(*f);
|
||||
// under non error circumstances this should be true
|
||||
if (functionType->interfaceFunctionType())
|
||||
externalDeclarations[functionType->externalSignature()].push_back(
|
||||
make_pair(f, functionType->asCallableFunction(false))
|
||||
);
|
||||
}
|
||||
for (VariableDeclaration const* v: contract->stateVariables())
|
||||
if (v->isPartOfExternalInterface())
|
||||
{
|
||||
auto functionType = make_shared<FunctionType>(*v);
|
||||
// under non error circumstances this should be true
|
||||
if (functionType->interfaceFunctionType())
|
||||
externalDeclarations[functionType->externalSignature()].push_back(
|
||||
make_pair(v, functionType->asCallableFunction(false))
|
||||
);
|
||||
}
|
||||
}
|
||||
for (auto const& it: externalDeclarations)
|
||||
for (size_t i = 0; i < it.second.size(); ++i)
|
||||
for (size_t j = i + 1; j < it.second.size(); ++j)
|
||||
if (!it.second[i].second->hasEqualParameterTypes(*it.second[j].second))
|
||||
m_errorReporter.typeError(
|
||||
it.second[j].first->location(),
|
||||
"Function overload clash during conversion to external types for arguments."
|
||||
);
|
||||
}
|
||||
|
||||
void TypeChecker::checkLibraryRequirements(ContractDefinition const& _contract)
|
||||
{
|
||||
solAssert(_contract.isLibrary(), "");
|
||||
|
@ -66,9 +66,6 @@ public:
|
||||
private:
|
||||
|
||||
bool visit(ContractDefinition const& _contract) override;
|
||||
/// Checks that different functions with external visibility end up having different
|
||||
/// external argument types (i.e. different signature).
|
||||
void checkContractExternalTypeClashes(ContractDefinition const& _contract);
|
||||
/// Checks that all requirements for a library are fulfilled if this is a library.
|
||||
void checkLibraryRequirements(ContractDefinition const& _contract);
|
||||
/// Checks (and warns) if a tuple assignment might cause unexpected overwrites in storage.
|
||||
|
Loading…
Reference in New Issue
Block a user