diff options
-rw-r--r-- | libsolidity/analysis/SyntaxChecker.cpp | 21 | ||||
-rw-r--r-- | libsolidity/analysis/SyntaxChecker.h | 9 | ||||
-rw-r--r-- | test/libsolidity/SolidityNameAndTypeResolution.cpp | 10 |
3 files changed, 39 insertions, 1 deletions
diff --git a/libsolidity/analysis/SyntaxChecker.cpp b/libsolidity/analysis/SyntaxChecker.cpp index e94ce9fe..593f2f69 100644 --- a/libsolidity/analysis/SyntaxChecker.cpp +++ b/libsolidity/analysis/SyntaxChecker.cpp @@ -40,13 +40,26 @@ void SyntaxChecker::syntaxError(SourceLocation const& _location, std::string con m_errors.push_back(err); } +bool SyntaxChecker::visit(ModifierDefinition const&) +{ + m_placeholderFound = false; + return true; +} + +void SyntaxChecker::endVisit(ModifierDefinition const& _modifier) +{ + if (!m_placeholderFound) + syntaxError(_modifier.body().location(), "Modifier body does not contain '_'."); + m_placeholderFound = false; +} + bool SyntaxChecker::visit(WhileStatement const&) { m_inLoopDepth++; return true; } -void SyntaxChecker::endVisit(WhileStatement const&) +void SyntaxChecker::endVisit(WhileStatement const& ) { m_inLoopDepth--; } @@ -78,3 +91,9 @@ bool SyntaxChecker::visit(Break const& _breakStatement) return true; } +bool SyntaxChecker::visit(const PlaceholderStatement&) +{ + m_placeholderFound = true; + return true; +} + diff --git a/libsolidity/analysis/SyntaxChecker.h b/libsolidity/analysis/SyntaxChecker.h index c836d49f..3198ffd0 100644 --- a/libsolidity/analysis/SyntaxChecker.h +++ b/libsolidity/analysis/SyntaxChecker.h @@ -31,6 +31,7 @@ namespace solidity /** * The module that performs syntax analysis on the AST: * - whether continue/break is in a for/while loop. + * - whether a modifier contains at least one '_' */ class SyntaxChecker: private ASTConstVisitor { @@ -44,6 +45,9 @@ private: /// Adds a new error to the list of errors. void syntaxError(SourceLocation const& _location, std::string const& _description); + virtual bool visit(ModifierDefinition const& _modifier) override; + virtual void endVisit(ModifierDefinition const& _modifier) override; + virtual bool visit(WhileStatement const& _whileStatement) override; virtual void endVisit(WhileStatement const& _whileStatement) override; virtual bool visit(ForStatement const& _forStatement) override; @@ -52,8 +56,13 @@ private: virtual bool visit(Continue const& _continueStatement) override; virtual bool visit(Break const& _breakStatement) override; + virtual bool visit(PlaceholderStatement const& _placeholderStatement) override; + ErrorList& m_errors; + /// Flag that indicates whether a function modifier actually contains '_'. + bool m_placeholderFound = false; + int m_inLoopDepth = 0; }; diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 7e81bd7e..2e00a510 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -3823,6 +3823,16 @@ BOOST_AUTO_TEST_CASE(unused_return_value_delegatecall) BOOST_CHECK(expectError(text, true) == Error::Type::Warning); } +BOOST_AUTO_TEST_CASE(modifier_without_underscore) +{ + char const* text = R"( + contract test { + modifier m() {} + } + )"; + BOOST_CHECK(expectError(text, true) == Error::Type::SyntaxError); +} + BOOST_AUTO_TEST_SUITE_END() } |