Merge pull request #11484 from ethereum/fix-unreachable-code-anaysis

Fix revert pruner modifying function flows wrong
This commit is contained in:
chriseth
2021-06-04 12:44:35 +02:00
committed by GitHub
9 changed files with 35 additions and 3 deletions
+17 -3
View File
@@ -260,6 +260,7 @@ bool ControlFlowBuilder::visit(PlaceholderStatement const&)
bool ControlFlowBuilder::visit(FunctionCall const& _functionCall)
{
solAssert(!!m_revertNode, "");
solAssert(!!m_currentNode, "");
solAssert(!!_functionCall.expression().annotation().type, "");
@@ -267,30 +268,43 @@ bool ControlFlowBuilder::visit(FunctionCall const& _functionCall)
switch (functionType->kind())
{
case FunctionType::Kind::Revert:
solAssert(!!m_revertNode, "");
visitNode(_functionCall);
_functionCall.expression().accept(*this);
ASTNode::listAccept(_functionCall.arguments(), *this);
connect(m_currentNode, m_revertNode);
m_currentNode = newLabel();
return false;
case FunctionType::Kind::Require:
case FunctionType::Kind::Assert:
{
solAssert(!!m_revertNode, "");
visitNode(_functionCall);
_functionCall.expression().accept(*this);
ASTNode::listAccept(_functionCall.arguments(), *this);
connect(m_currentNode, m_revertNode);
auto nextNode = newLabel();
connect(m_currentNode, nextNode);
m_currentNode = nextNode;
return false;
}
case FunctionType::Kind::Internal:
{
visitNode(_functionCall);
_functionCall.expression().accept(*this);
ASTNode::listAccept(_functionCall.arguments(), *this);
m_currentNode->functionCalls.emplace_back(&_functionCall);
break;
auto nextNode = newLabel();
connect(m_currentNode, nextNode);
m_currentNode = nextNode;
return false;
}
default:
break;
@@ -20,6 +20,8 @@
#include <libsolutil/Algorithms.h>
#include <range/v3/algorithm/remove.hpp>
namespace solidity::frontend
{
@@ -192,7 +194,11 @@ void ControlFlowRevertPruner::modifyFunctionFlows()
// change anymore, we treat all "unknown" states as
// "reverting", since they can only be caused by
// recursion.
for (CFGNode * node: _node->exits)
ranges::remove(node->entries, _node);
_node->exits = {functionFlow.revert};
functionFlow.revert->entries.push_back(_node);
return;
default:
break;