Ensure list of overrides consists of contracts

This commit is contained in:
Mathias Baumann 2019-09-16 12:36:50 +02:00
parent b76106fc4a
commit 20e227afb5
3 changed files with 49 additions and 0 deletions

View File

@ -60,6 +60,27 @@ void PostTypeChecker::endVisit(ContractDefinition const&)
m_constVariableDependencies.clear();
}
void PostTypeChecker::endVisit(OverrideSpecifier const& _overrideSpecifier)
{
for (ASTPointer<UserDefinedTypeName> const& override: _overrideSpecifier.overrides())
{
Declaration const* decl = override->annotation().referencedDeclaration;
solAssert(decl, "Expected declaration to be resolved.");
if (dynamic_cast<ContractDefinition const*>(decl))
continue;
TypeType const* actualTypeType = dynamic_cast<TypeType const*>(decl->type());
m_errorReporter.typeError(
override->location(),
"Expected contract but got " +
actualTypeType->actualType()->toString(true) +
"."
);
}
}
bool PostTypeChecker::visit(VariableDeclaration const& _variable)
{
solAssert(!m_currentConstVariable, "");

View File

@ -37,6 +37,7 @@ namespace solidity
/**
* This module performs analyses on the AST that are done after type checking and assignments of types:
* - whether there are circular references in constant state variables
* - whether override specifiers are actually contracts
* @TODO factor out each use-case into an individual class (but do the traversal only once)
*/
class PostTypeChecker: private ASTConstVisitor
@ -53,6 +54,7 @@ private:
bool visit(ContractDefinition const& _contract) override;
void endVisit(ContractDefinition const& _contract) override;
void endVisit(OverrideSpecifier const& _overrideSpecifier) override;
bool visit(VariableDeclaration const& _variable) override;
void endVisit(VariableDeclaration const& _variable) override;

View File

@ -0,0 +1,26 @@
contract A {
int public testvar;
function foo() internal returns (uint256);
function test(uint8 _a) internal returns (uint256);
}
contract B {
function foo() internal returns (uint256);
function test() internal returns (uint256);
}
contract C {
function foo() internal returns (uint256);
}
contract D {
function foo() internal returns (uint256);
}
contract X is A, B, C, D {
struct MyStruct { int abc; }
enum ENUM { F,G,H }
int public override testvar;
function test() internal override returns (uint256);
function foo() internal override(MyStruct, ENUM, A, B, C, D) returns (uint256);
}
// ----
// TypeError: (552-560): Expected contract but got struct X.MyStruct.
// TypeError: (562-566): Expected contract but got enum X.ENUM.