mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Fix revert pruner modifying function flows wrong
This commit is contained in:
parent
424edcc562
commit
d8ffdf11c8
@ -44,6 +44,7 @@ this nonsensical example::
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.22 <0.9.0;
|
||||
|
||||
// This will report a warning
|
||||
contract C {
|
||||
function g(uint a) public pure returns (uint ret) { return a + f(); }
|
||||
function f() internal pure returns (uint ret) { return g(7) + f(); }
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user