diff --git a/libsolidity/analysis/ControlFlowBuilder.cpp b/libsolidity/analysis/ControlFlowBuilder.cpp index 7c568b18e..06787a512 100644 --- a/libsolidity/analysis/ControlFlowBuilder.cpp +++ b/libsolidity/analysis/ControlFlowBuilder.cpp @@ -17,6 +17,7 @@ // SPDX-License-Identifier: GPL-3.0 #include +#include #include #include @@ -617,11 +618,7 @@ bool ControlFlowBuilder::visit(VariableDeclarationStatement const& _variableDecl solAssert(tupleExpression->components().size() > i, ""); expression = tupleExpression->components()[i].get(); } - while (auto tupleExpression = dynamic_cast(expression)) - if (tupleExpression->components().size() == 1) - expression = tupleExpression->components().front().get(); - else - break; + expression = resolveUnaryTuples(expression); m_currentNode->variableOccurrences.emplace_back( *var, VariableOccurrence::Kind::Assignment, diff --git a/libsolidity/ast/ASTUtils.cpp b/libsolidity/ast/ASTUtils.cpp index 2b7ea7427..b4e75bace 100644 --- a/libsolidity/ast/ASTUtils.cpp +++ b/libsolidity/ast/ASTUtils.cpp @@ -85,4 +85,14 @@ VariableDeclaration const* rootConstVariableDeclaration(VariableDeclaration cons return rootDecl; } +Expression const* resolveUnaryTuples(Expression const* _expr) +{ + while (auto const* tupleExpression = dynamic_cast(_expr)) + if (tupleExpression->components().size() == 1) + _expr = tupleExpression->components().front().get(); + else + break; + return _expr; +} + } diff --git a/libsolidity/ast/ASTUtils.h b/libsolidity/ast/ASTUtils.h index 2bfbb8fe9..7ec79ef1b 100644 --- a/libsolidity/ast/ASTUtils.h +++ b/libsolidity/ast/ASTUtils.h @@ -38,4 +38,8 @@ bool isConstantVariableRecursive(VariableDeclaration const& _varDecl); /// Returns the innermost AST node that covers the given location or nullptr if not found. ASTNode const* locateInnermostASTNode(int _offsetInFile, SourceUnit const& _sourceUnit); +/// @returns @a _expr itself, in case it is not an unary tuple expression. Otherwise it descends recursively +/// into unary tuples and returns the contained expression. +Expression const* resolveUnaryTuples(Expression const* _expr); + }