From cb548f6f530cf52d8490fb194623888126bd85d4 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 11 Apr 2018 17:27:06 +0200 Subject: [PATCH] Fix ConstantEvaluator to correctly handle single element tuples. --- Changelog.md | 1 + libsolidity/analysis/ConstantEvaluator.cpp | 6 +++++ libsolidity/analysis/ConstantEvaluator.h | 1 + .../syntaxTests/arrayLength/inline_array.sol | 5 ++++ .../syntaxTests/arrayLength/parentheses.sol | 25 +++++++++++++++++++ .../syntaxTests/arrayLength/tuples.sol | 5 ++++ 6 files changed, 43 insertions(+) create mode 100644 test/libsolidity/syntaxTests/arrayLength/inline_array.sol create mode 100644 test/libsolidity/syntaxTests/arrayLength/parentheses.sol create mode 100644 test/libsolidity/syntaxTests/arrayLength/tuples.sol diff --git a/Changelog.md b/Changelog.md index 6df11f275..1612fe3bd 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,7 @@ Features: * Code Generator: Initialize arrays without using ``msize()``. * Code Generator: More specialized and thus optimized implementation for ``x.push(...)`` * Commandline interface: Error when missing or inaccessible file detected. Suppress it with the ``--ignore-missing`` flag. + * Constant Evaluator: Fix evaluation of single element tuples. * General: Limit the number of errors output in a single run to 256. * General: Support accessing dynamic return data in post-byzantium EVMs. * Interfaces: Allow overriding external functions in interfaces with public in an implementing contract. diff --git a/libsolidity/analysis/ConstantEvaluator.cpp b/libsolidity/analysis/ConstantEvaluator.cpp index 83f37f474..8659bbfdc 100644 --- a/libsolidity/analysis/ConstantEvaluator.cpp +++ b/libsolidity/analysis/ConstantEvaluator.cpp @@ -87,6 +87,12 @@ void ConstantEvaluator::endVisit(Identifier const& _identifier) setType(_identifier, type(*value)); } +void ConstantEvaluator::endVisit(TupleExpression const& _tuple) +{ + if (!_tuple.isInlineArray() && _tuple.components().size() == 1) + setType(_tuple, type(*_tuple.components().front())); +} + void ConstantEvaluator::setType(ASTNode const& _node, TypePointer const& _type) { if (_type && _type->category() == Type::Category::RationalNumber) diff --git a/libsolidity/analysis/ConstantEvaluator.h b/libsolidity/analysis/ConstantEvaluator.h index 77a357b65..ac3a24a1f 100644 --- a/libsolidity/analysis/ConstantEvaluator.h +++ b/libsolidity/analysis/ConstantEvaluator.h @@ -56,6 +56,7 @@ private: virtual void endVisit(UnaryOperation const& _operation); virtual void endVisit(Literal const& _literal); virtual void endVisit(Identifier const& _identifier); + virtual void endVisit(TupleExpression const& _tuple); void setType(ASTNode const& _node, TypePointer const& _type); TypePointer type(ASTNode const& _node); diff --git a/test/libsolidity/syntaxTests/arrayLength/inline_array.sol b/test/libsolidity/syntaxTests/arrayLength/inline_array.sol new file mode 100644 index 000000000..a30745d32 --- /dev/null +++ b/test/libsolidity/syntaxTests/arrayLength/inline_array.sol @@ -0,0 +1,5 @@ +contract C { + uint[[2]] a15; +} +// ---- +// TypeError: (22-25): Invalid array length, expected integer literal or constant expression. diff --git a/test/libsolidity/syntaxTests/arrayLength/parentheses.sol b/test/libsolidity/syntaxTests/arrayLength/parentheses.sol new file mode 100644 index 000000000..40f55ad63 --- /dev/null +++ b/test/libsolidity/syntaxTests/arrayLength/parentheses.sol @@ -0,0 +1,25 @@ +contract C { + uint constant L1 = (2); + uint constant L2 = ((2)); + uint constant L3 = ((((2)))); + uint constant L4 = (2 + 1); + uint constant L5 = ((2 + 1)); + uint constant L6 = (((2) + ((1)))); + uint constant L7 = (2 + 1) / 1; + uint constant L8 = (2 + ((1))) / (1); + uint[L1] a1; + uint[L2] a2; + uint[L3] a3; + uint[L4] a4; + uint[L5] a5; + uint[L6] a6; + uint[L7] a7; + uint[L8] a8; + uint[(2)] a9; + uint[(2 + 1)] a10; + uint[(2 + 1) + 1] a11; + uint[((2) + 1) + 1] a12; + uint[(2 + 1) + ((1))] a13; + uint[(((2) + 1)) + (((1)))] a14; + uint[((((2) + 1)) + (((1))))%1] a15; +} diff --git a/test/libsolidity/syntaxTests/arrayLength/tuples.sol b/test/libsolidity/syntaxTests/arrayLength/tuples.sol new file mode 100644 index 000000000..bc10b3b5d --- /dev/null +++ b/test/libsolidity/syntaxTests/arrayLength/tuples.sol @@ -0,0 +1,5 @@ +contract C { + uint[(1,2)] a15; +} +// ---- +// TypeError: (22-27): Invalid array length, expected integer literal or constant expression.