diff options
-rw-r--r-- | CODING_STYLE.md | 2 | ||||
-rw-r--r-- | docs/solidity-by-example.rst | 1 | ||||
-rw-r--r-- | libyul/optimiser/ExpressionJoiner.cpp | 30 | ||||
-rw-r--r-- | libyul/optimiser/ExpressionJoiner.h | 26 |
4 files changed, 22 insertions, 37 deletions
diff --git a/CODING_STYLE.md b/CODING_STYLE.md index 8101db0c..a0fe9864 100644 --- a/CODING_STYLE.md +++ b/CODING_STYLE.md @@ -146,7 +146,7 @@ for (auto i = x->begin(); i != x->end(); ++i) {} ``` No: -```cp +```cpp const double d = 0; int i, j; char *s; diff --git a/docs/solidity-by-example.rst b/docs/solidity-by-example.rst index 8f58f339..f71f1e23 100644 --- a/docs/solidity-by-example.rst +++ b/docs/solidity-by-example.rst @@ -152,6 +152,7 @@ of votes. /// to proposal `proposals[proposal].name`. function vote(uint proposal) public { Voter storage sender = voters[msg.sender]; + require(sender.weight != 0, "Has no right to vote"); require(!sender.voted, "Already voted."); sender.voted = true; sender.vote = proposal; diff --git a/libyul/optimiser/ExpressionJoiner.cpp b/libyul/optimiser/ExpressionJoiner.cpp index c3957497..7e57a629 100644 --- a/libyul/optimiser/ExpressionJoiner.cpp +++ b/libyul/optimiser/ExpressionJoiner.cpp @@ -46,20 +46,6 @@ void ExpressionJoiner::operator()(FunctionCall& _funCall) handleArguments(_funCall.arguments); } -void ExpressionJoiner::operator()(If& _if) -{ - visit(*_if.condition); - (*this)(_if.body); -} - -void ExpressionJoiner::operator()(Switch& _switch) -{ - visit(*_switch.expression); - for (auto& _case: _switch.cases) - // Do not visit the case expression, nothing to join there. - (*this)(_case.body); -} - void ExpressionJoiner::operator()(Block& _block) { resetLatestStatementPointer(); @@ -79,13 +65,11 @@ void ExpressionJoiner::visit(Expression& _e) if (_e.type() == typeid(Identifier)) { Identifier const& identifier = boost::get<Identifier>(_e); - if (isLatestStatementVarDeclOf(identifier) && m_references[identifier.name] == 1) + if (isLatestStatementVarDeclJoinable(identifier)) { VariableDeclaration& varDecl = boost::get<VariableDeclaration>(*latestStatement()); - assertThrow(varDecl.variables.size() == 1, OptimizerException, ""); - assertThrow(varDecl.value, OptimizerException, ""); - _e = std::move(*varDecl.value); + // Delete the variable declaration (also get the moved-from structure back into a sane state) *latestStatement() = Block(); @@ -103,9 +87,7 @@ void ExpressionJoiner::run(Block& _ast) ExpressionJoiner::ExpressionJoiner(Block& _ast) { - ReferencesCounter counter; - counter(_ast); - m_references = counter.references(); + m_references = ReferencesCounter::countReferences(_ast); } void ExpressionJoiner::handleArguments(vector<Expression>& _arguments) @@ -154,7 +136,7 @@ Statement* ExpressionJoiner::latestStatement() return &m_currentBlock->statements.at(m_latestStatementInBlock); } -bool ExpressionJoiner::isLatestStatementVarDeclOf(Identifier const& _identifier) +bool ExpressionJoiner::isLatestStatementVarDeclJoinable(Identifier const& _identifier) { Statement const* statement = latestStatement(); if (!statement || statement->type() != typeid(VariableDeclaration)) @@ -162,5 +144,7 @@ bool ExpressionJoiner::isLatestStatementVarDeclOf(Identifier const& _identifier) VariableDeclaration const& varDecl = boost::get<VariableDeclaration>(*statement); if (varDecl.variables.size() != 1 || !varDecl.value) return false; - return varDecl.variables.at(0).name == _identifier.name; + assertThrow(varDecl.variables.size() == 1, OptimizerException, ""); + assertThrow(varDecl.value, OptimizerException, ""); + return varDecl.variables.at(0).name == _identifier.name && m_references[_identifier.name] == 1; } diff --git a/libyul/optimiser/ExpressionJoiner.h b/libyul/optimiser/ExpressionJoiner.h index df18e58f..4f06cc0f 100644 --- a/libyul/optimiser/ExpressionJoiner.h +++ b/libyul/optimiser/ExpressionJoiner.h @@ -73,29 +73,29 @@ class NameCollector; class ExpressionJoiner: public ASTModifier { public: - virtual void operator()(FunctionalInstruction&) override; - virtual void operator()(FunctionCall&) override; - virtual void operator()(If&) override; - virtual void operator()(Switch&) override; - virtual void operator()(Block& _block) override; - - using ASTModifier::visit; - virtual void visit(Expression& _e) override; - static void run(Block& _ast); + private: explicit ExpressionJoiner(Block& _ast); + void operator()(Block& _block) override; + void operator()(FunctionalInstruction&) override; + void operator()(FunctionCall&) override; + + using ASTModifier::visit; + void visit(Expression& _e) override; + void handleArguments(std::vector<Expression>& _arguments); void decrementLatestStatementPointer(); void resetLatestStatementPointer(); Statement* latestStatement(); - bool isLatestStatementVarDeclOf(Identifier const& _identifier); + bool isLatestStatementVarDeclJoinable(Identifier const& _identifier); - Block* m_currentBlock = nullptr; - size_t m_latestStatementInBlock = 0; - std::map<std::string, size_t> m_references; +private: + Block* m_currentBlock = nullptr; ///< Pointer to currently block holding the visiting statement. + size_t m_latestStatementInBlock = 0; ///< Offset to m_currentBlock's statements of the last visited statement. + std::map<std::string, size_t> m_references; ///< Holds reference counts to all variable declarations in current block. }; } |