From 43a612e420675c452ee0e9876b3387fe866fdef2 Mon Sep 17 00:00:00 2001 From: wechman Date: Wed, 13 Jul 2022 10:29:54 +0200 Subject: [PATCH] Fix control flow check for unary operators --- libsolidity/analysis/ControlFlowBuilder.cpp | 10 +++++++--- .../binary_operator.sol | 17 +++++++++++++++++ .../userDefinedTypeOperators/unary_operator.sol | 15 +++++++++++++++ 3 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 test/libsolidity/syntaxTests/controlFlow/userDefinedTypeOperators/binary_operator.sol create mode 100644 test/libsolidity/syntaxTests/controlFlow/userDefinedTypeOperators/unary_operator.sol diff --git a/libsolidity/analysis/ControlFlowBuilder.cpp b/libsolidity/analysis/ControlFlowBuilder.cpp index a76775ad4..a1d10cfe8 100644 --- a/libsolidity/analysis/ControlFlowBuilder.cpp +++ b/libsolidity/analysis/ControlFlowBuilder.cpp @@ -63,6 +63,7 @@ bool ControlFlowBuilder::visit(BinaryOperation const& _operation) case Token::Or: case Token::And: { + visitNode(_operation); solAssert(!_operation.annotation().userDefinedFunction); visitNode(_operation); appendControlFlow(_operation.leftExpression()); @@ -75,9 +76,10 @@ bool ControlFlowBuilder::visit(BinaryOperation const& _operation) } default: { - bool result = ASTConstVisitor::visit(_operation); + visitNode(_operation); if (_operation.annotation().userDefinedFunction) { + visitNode(_operation); solAssert(!m_currentNode->resolveFunctionCall(nullptr)); m_currentNode->functionCall = _operation.annotation().userDefinedFunction; @@ -86,7 +88,7 @@ bool ControlFlowBuilder::visit(BinaryOperation const& _operation) connect(m_currentNode, nextNode); m_currentNode = nextNode; } - return result; + return true; } } } @@ -95,9 +97,9 @@ bool ControlFlowBuilder::visit(UnaryOperation const& _operation) { solAssert(!!m_currentNode, ""); - ASTConstVisitor::visit(_operation); if (_operation.annotation().userDefinedFunction) { + visitNode(_operation); solAssert(!m_currentNode->resolveFunctionCall(nullptr)); m_currentNode->functionCall = _operation.annotation().userDefinedFunction; @@ -105,7 +107,9 @@ bool ControlFlowBuilder::visit(UnaryOperation const& _operation) connect(m_currentNode, nextNode); m_currentNode = nextNode; + return true; } + return false; } diff --git a/test/libsolidity/syntaxTests/controlFlow/userDefinedTypeOperators/binary_operator.sol b/test/libsolidity/syntaxTests/controlFlow/userDefinedTypeOperators/binary_operator.sol new file mode 100644 index 000000000..ee323cbe8 --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/userDefinedTypeOperators/binary_operator.sol @@ -0,0 +1,17 @@ +struct S { bool f; } + +using {add as +} for S; + +function add(S storage x, S storage) pure returns (S storage) { return x; } + +contract C { + S s; + function f() public { + S storage x = s; + S storage y; + x + y; + } +} + +// ---- +// TypeError 3464: (230-231): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour. diff --git a/test/libsolidity/syntaxTests/controlFlow/userDefinedTypeOperators/unary_operator.sol b/test/libsolidity/syntaxTests/controlFlow/userDefinedTypeOperators/unary_operator.sol new file mode 100644 index 000000000..05a130225 --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/userDefinedTypeOperators/unary_operator.sol @@ -0,0 +1,15 @@ +struct S { int f; } + +using {sub as -} for S; + +function sub(S storage x) pure returns (S storage) { return x; } + +contract C { + function f() public { + S storage y; + -y; + } +} + +// ---- +// TypeError 3464: (181-182): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.