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);
|
checkBaseConstructorArguments(_contract);
|
||||||
checkConstructor(_contract);
|
checkConstructor(_contract);
|
||||||
checkFallbackFunction(_contract);
|
checkFallbackFunction(_contract);
|
||||||
|
checkExternalTypeClashes(_contract);
|
||||||
|
|
||||||
return Error::containsOnlyWarnings(m_errorReporter.errors());
|
return Error::containsOnlyWarnings(m_errorReporter.errors());
|
||||||
}
|
}
|
||||||
@ -383,3 +384,39 @@ void ContractLevelChecker::checkFallbackFunction(ContractDefinition const& _cont
|
|||||||
if (fallback->visibility() != FunctionDefinition::Visibility::External)
|
if (fallback->visibility() != FunctionDefinition::Visibility::External)
|
||||||
m_errorReporter.typeError(fallback->location(), "Fallback function must be defined as \"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 checkConstructor(ContractDefinition const& _contract);
|
||||||
void checkFallbackFunction(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;
|
langutil::ErrorReporter& m_errorReporter;
|
||||||
};
|
};
|
||||||
|
@ -93,7 +93,6 @@ bool TypeChecker::visit(ContractDefinition const& _contract)
|
|||||||
for (auto const& n: _contract.subNodes())
|
for (auto const& n: _contract.subNodes())
|
||||||
n->accept(*this);
|
n->accept(*this);
|
||||||
|
|
||||||
checkContractExternalTypeClashes(_contract);
|
|
||||||
// check for hash collisions in function signatures
|
// check for hash collisions in function signatures
|
||||||
set<FixedHash<4>> hashes;
|
set<FixedHash<4>> hashes;
|
||||||
for (auto const& it: _contract.interfaceFunctionList())
|
for (auto const& it: _contract.interfaceFunctionList())
|
||||||
@ -113,42 +112,6 @@ bool TypeChecker::visit(ContractDefinition const& _contract)
|
|||||||
return false;
|
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)
|
void TypeChecker::checkLibraryRequirements(ContractDefinition const& _contract)
|
||||||
{
|
{
|
||||||
solAssert(_contract.isLibrary(), "");
|
solAssert(_contract.isLibrary(), "");
|
||||||
|
@ -66,9 +66,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
bool visit(ContractDefinition const& _contract) override;
|
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.
|
/// Checks that all requirements for a library are fulfilled if this is a library.
|
||||||
void checkLibraryRequirements(ContractDefinition const& _contract);
|
void checkLibraryRequirements(ContractDefinition const& _contract);
|
||||||
/// Checks (and warns) if a tuple assignment might cause unexpected overwrites in storage.
|
/// Checks (and warns) if a tuple assignment might cause unexpected overwrites in storage.
|
||||||
|
Loading…
Reference in New Issue
Block a user