From 20e227afb543195f2927224e822d4c230298b630 Mon Sep 17 00:00:00 2001 From: Mathias Baumann Date: Mon, 16 Sep 2019 12:36:50 +0200 Subject: [PATCH] Ensure list of overrides consists of contracts --- libsolidity/analysis/PostTypeChecker.cpp | 21 +++++++++++++++ libsolidity/analysis/PostTypeChecker.h | 2 ++ .../override/override_type_mismatch.sol | 26 +++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 test/libsolidity/syntaxTests/inheritance/override/override_type_mismatch.sol diff --git a/libsolidity/analysis/PostTypeChecker.cpp b/libsolidity/analysis/PostTypeChecker.cpp index 936e133ca..40c4f22d8 100644 --- a/libsolidity/analysis/PostTypeChecker.cpp +++ b/libsolidity/analysis/PostTypeChecker.cpp @@ -60,6 +60,27 @@ void PostTypeChecker::endVisit(ContractDefinition const&) m_constVariableDependencies.clear(); } +void PostTypeChecker::endVisit(OverrideSpecifier const& _overrideSpecifier) +{ + for (ASTPointer const& override: _overrideSpecifier.overrides()) + { + Declaration const* decl = override->annotation().referencedDeclaration; + solAssert(decl, "Expected declaration to be resolved."); + + if (dynamic_cast(decl)) + continue; + + TypeType const* actualTypeType = dynamic_cast(decl->type()); + + m_errorReporter.typeError( + override->location(), + "Expected contract but got " + + actualTypeType->actualType()->toString(true) + + "." + ); + } +} + bool PostTypeChecker::visit(VariableDeclaration const& _variable) { solAssert(!m_currentConstVariable, ""); diff --git a/libsolidity/analysis/PostTypeChecker.h b/libsolidity/analysis/PostTypeChecker.h index e428b81ae..b4441b395 100644 --- a/libsolidity/analysis/PostTypeChecker.h +++ b/libsolidity/analysis/PostTypeChecker.h @@ -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; diff --git a/test/libsolidity/syntaxTests/inheritance/override/override_type_mismatch.sol b/test/libsolidity/syntaxTests/inheritance/override/override_type_mismatch.sol new file mode 100644 index 000000000..c7b120a4e --- /dev/null +++ b/test/libsolidity/syntaxTests/inheritance/override/override_type_mismatch.sol @@ -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.