From c5923f7fcfb7dfb136567a9ecefff9f14f3c532a Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 22 Jun 2021 15:33:19 +0200 Subject: [PATCH] Prevent calls to unimplemented modifiers. --- Changelog.md | 1 + libsolidity/analysis/TypeChecker.cpp | 9 +++++++++ .../modifiers/use_unimplemented_static.sol | 12 ++++++++++++ 3 files changed, 22 insertions(+) create mode 100644 test/libsolidity/syntaxTests/modifiers/use_unimplemented_static.sol diff --git a/Changelog.md b/Changelog.md index 28b61f7ac..64b87b425 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,6 +8,7 @@ Compiler Features: Bugfixes: * Code Generator: Fix internal compiler error when calling functions bound to calldata structs and arrays. + * Type Checker: Fix internal error and prevent static calls to unimplemented modifiers. ### 0.8.6 (2021-06-22) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index c51a8ad0e..7bc1ff833 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -639,6 +639,15 @@ void TypeChecker::visitManually( "Can only use modifiers defined in the current contract or in base contracts." ); } + if ( + *_modifier.name().annotation().requiredLookup == VirtualLookup::Static && + !modifierDecl->isImplemented() + ) + m_errorReporter.typeError( + 1835_error, + _modifier.location(), + "Cannot call unimplemented modifier. The modifier has no implementation in the referenced contract. Refer to it by its unqualified name if you want to call the implementation from the most derived contract." + ); } else // check parameters for Base constructors diff --git a/test/libsolidity/syntaxTests/modifiers/use_unimplemented_static.sol b/test/libsolidity/syntaxTests/modifiers/use_unimplemented_static.sol new file mode 100644 index 000000000..a6fcd7eaf --- /dev/null +++ b/test/libsolidity/syntaxTests/modifiers/use_unimplemented_static.sol @@ -0,0 +1,12 @@ +contract A { + modifier m() virtual { _; } +} +abstract contract B { + modifier m() virtual; +} +contract C is A, B { + modifier m() override(A, B) { _; } + function f() B.m public {} +} +// ---- +// TypeError 1835: (174-177): Cannot call unimplemented modifier. The modifier has no implementation in the referenced contract. Refer to it by its unqualified name if you want to call the implementation from the most derived contract.