aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Beregszaszi <alex@rtfs.hu>2018-04-12 02:49:21 +0800
committerGitHub <noreply@github.com>2018-04-12 02:49:21 +0800
commit418e2725b50aebc169dd80f78a0ce3eefc2e296e (patch)
tree6ca950c91d2dba0f44a24ed59b775e5588e8a537
parentd50d1f0ac1841a1d287a216451e93573fc07474e (diff)
parentcb548f6f530cf52d8490fb194623888126bd85d4 (diff)
downloaddexon-solidity-418e2725b50aebc169dd80f78a0ce3eefc2e296e.tar.gz
dexon-solidity-418e2725b50aebc169dd80f78a0ce3eefc2e296e.tar.zst
dexon-solidity-418e2725b50aebc169dd80f78a0ce3eefc2e296e.zip
Merge pull request #3862 from ethereum/fixConstantEvaluatorTuples
Fix ConstantEvaluator to correctly handle single element tuples (i.e. parenthesis).
-rw-r--r--Changelog.md1
-rw-r--r--libsolidity/analysis/ConstantEvaluator.cpp6
-rw-r--r--libsolidity/analysis/ConstantEvaluator.h1
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp165
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/array_length_cannot_be_constant_function_parameter.sol7
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/can_be_constant_in_function.sol8
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/can_be_constant_in_struct.sol7
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/can_be_recursive_constant.sol6
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/cannot_be_function.sol6
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/cannot_be_function_call.sol7
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/complex_cyclic_constant.sol10
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/const_cannot_be_fractional.sol6
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/constant_var.sol5
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/cyclic_constant.sol8
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/inline_array.sol5
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/invalid_expression_1.sol5
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/invalid_expression_2.sol5
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/invalid_expression_3.sol5
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/invalid_expression_4.sol5
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/invalid_expression_5.sol5
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/non_integer_constant_var.sol6
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/not_convertible_to_integer.sol5
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/parentheses.sol25
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/pure_functions.sol6
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/too_large.sol5
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/tuples.sol5
26 files changed, 160 insertions, 165 deletions
diff --git a/Changelog.md b/Changelog.md
index 6df11f27..1612fe3b 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 83f37f47..8659bbfd 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 77a357b6..ac3a24a1 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/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index fcee0df3..293f5f44 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -7720,171 +7720,6 @@ BOOST_AUTO_TEST_CASE(address_overload_resolution)
CHECK_SUCCESS(text);
}
-BOOST_AUTO_TEST_CASE(array_length_too_large)
-{
- char const* text = R"(
- contract C {
- uint[8**90] ids;
- }
- )";
- CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal or constant expression.");
-}
-
-BOOST_AUTO_TEST_CASE(array_length_not_convertible_to_integer)
-{
- char const* text = R"(
- contract C {
- uint[true] ids;
- }
- )";
- CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal or constant expression.");
-}
-
-BOOST_AUTO_TEST_CASE(array_length_constant_var)
-{
- char const* text = R"(
- contract C {
- uint constant LEN = 10;
- uint[LEN] ids;
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(array_length_non_integer_constant_var)
-{
- char const* text = R"(
- contract C {
- bool constant LEN = true;
- uint[LEN] ids;
- }
- )";
- CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal or constant expression.");
-}
-
-BOOST_AUTO_TEST_CASE(array_length_cannot_be_function)
-{
- char const* text = R"(
- contract C {
- function f() {}
- uint[f] ids;
- }
- )";
- CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal or constant expression.");
-}
-
-BOOST_AUTO_TEST_CASE(array_length_can_be_recursive_constant)
-{
- char const* text = R"(
- contract C {
- uint constant L = 5;
- uint constant LEN = L + 4 * L;
- uint[LEN] ids;
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(array_length_cannot_be_function_call)
-{
- char const* text = R"(
- contract C {
- function f(uint x) {}
- uint constant LEN = f();
- uint[LEN] ids;
- }
- )";
- CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal or constant expression.");
-}
-
-BOOST_AUTO_TEST_CASE(array_length_const_cannot_be_fractional)
-{
- char const* text = R"(
- contract C {
- fixed constant L = 10.5;
- uint[L] ids;
- }
- )";
- CHECK_ERROR(text, TypeError, "Array with fractional length specified");
-}
-
-BOOST_AUTO_TEST_CASE(array_length_can_be_constant_in_struct)
-{
- char const* text = R"(
- contract C {
- uint constant LEN = 10;
- struct Test {
- uint[LEN] ids;
- }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(array_length_can_be_constant_in_function)
-{
- char const* text = R"(
- contract C {
- uint constant LEN = 10;
- function f() {
- uint[LEN] a;
- }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(array_length_cannot_be_constant_function_parameter)
-{
- char const* text = R"(
- contract C {
- function f(uint constant LEN) {
- uint[LEN] a;
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal or constant expression.");
-}
-
-BOOST_AUTO_TEST_CASE(array_length_with_cyclic_constant)
-{
- char const* text = R"(
- contract C {
- uint constant LEN = LEN;
- function f() {
- uint[LEN] a;
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Cyclic constant definition (or maximum recursion depth exhausted).");
-}
-
-BOOST_AUTO_TEST_CASE(array_length_with_complex_cyclic_constant)
-{
- char const* text = R"(
- contract C {
- uint constant L2 = LEN - 10;
- uint constant L1 = L2 / 10;
- uint constant LEN = 10 + L1 * 5;
- function f() {
- uint[LEN] a;
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Cyclic constant definition (or maximum recursion depth exhausted).");
-}
-
-BOOST_AUTO_TEST_CASE(array_length_with_pure_functions)
-{
- char const* text = R"(
- contract C {
- uint constant LEN = keccak256(ripemd160(33));
- uint[LEN] ids;
- }
- )";
- CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal or constant expression.");
-}
-
BOOST_AUTO_TEST_CASE(array_length_invalid_expression)
{
char const* text = R"(
diff --git a/test/libsolidity/syntaxTests/arrayLength/array_length_cannot_be_constant_function_parameter.sol b/test/libsolidity/syntaxTests/arrayLength/array_length_cannot_be_constant_function_parameter.sol
new file mode 100644
index 00000000..11d40f26
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/array_length_cannot_be_constant_function_parameter.sol
@@ -0,0 +1,7 @@
+contract C {
+ function f(uint constant LEN) {
+ uint[LEN] a;
+ }
+}
+// ----
+// TypeError: (62-65): Invalid array length, expected integer literal or constant expression.
diff --git a/test/libsolidity/syntaxTests/arrayLength/can_be_constant_in_function.sol b/test/libsolidity/syntaxTests/arrayLength/can_be_constant_in_function.sol
new file mode 100644
index 00000000..92536dd5
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/can_be_constant_in_function.sol
@@ -0,0 +1,8 @@
+contract C {
+ uint constant LEN = 10;
+ function f() public pure {
+ uint[LEN] memory a;
+ a;
+ }
+}
+// ----
diff --git a/test/libsolidity/syntaxTests/arrayLength/can_be_constant_in_struct.sol b/test/libsolidity/syntaxTests/arrayLength/can_be_constant_in_struct.sol
new file mode 100644
index 00000000..89e174f2
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/can_be_constant_in_struct.sol
@@ -0,0 +1,7 @@
+contract C {
+ uint constant LEN = 10;
+ struct Test {
+ uint[LEN] ids;
+ }
+}
+// ----
diff --git a/test/libsolidity/syntaxTests/arrayLength/can_be_recursive_constant.sol b/test/libsolidity/syntaxTests/arrayLength/can_be_recursive_constant.sol
new file mode 100644
index 00000000..6810a9d6
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/can_be_recursive_constant.sol
@@ -0,0 +1,6 @@
+contract C {
+ uint constant L = 5;
+ uint constant LEN = L + 4 * L;
+ uint[LEN] ids;
+}
+// ----
diff --git a/test/libsolidity/syntaxTests/arrayLength/cannot_be_function.sol b/test/libsolidity/syntaxTests/arrayLength/cannot_be_function.sol
new file mode 100644
index 00000000..ac3abc4c
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/cannot_be_function.sol
@@ -0,0 +1,6 @@
+contract C {
+ function f() {}
+ uint[f] ids;
+}
+// ----
+// TypeError: (42-43): Invalid array length, expected integer literal or constant expression.
diff --git a/test/libsolidity/syntaxTests/arrayLength/cannot_be_function_call.sol b/test/libsolidity/syntaxTests/arrayLength/cannot_be_function_call.sol
new file mode 100644
index 00000000..a6863955
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/cannot_be_function_call.sol
@@ -0,0 +1,7 @@
+contract C {
+ function f(uint x) {}
+ uint constant LEN = f();
+ uint[LEN] ids;
+}
+// ----
+// TypeError: (77-80): Invalid array length, expected integer literal or constant expression.
diff --git a/test/libsolidity/syntaxTests/arrayLength/complex_cyclic_constant.sol b/test/libsolidity/syntaxTests/arrayLength/complex_cyclic_constant.sol
new file mode 100644
index 00000000..254f9f02
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/complex_cyclic_constant.sol
@@ -0,0 +1,10 @@
+contract C {
+ uint constant L2 = LEN - 10;
+ uint constant L1 = L2 / 10;
+ uint constant LEN = 10 + L1 * 5;
+ function f() {
+ uint[LEN] a;
+ }
+}
+// ----
+// TypeError: (36-39): Cyclic constant definition (or maximum recursion depth exhausted).
diff --git a/test/libsolidity/syntaxTests/arrayLength/const_cannot_be_fractional.sol b/test/libsolidity/syntaxTests/arrayLength/const_cannot_be_fractional.sol
new file mode 100644
index 00000000..397bbbcd
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/const_cannot_be_fractional.sol
@@ -0,0 +1,6 @@
+contract C {
+ fixed constant L = 10.5;
+ uint[L] ids;
+}
+// ----
+// TypeError: (51-52): Array with fractional length specified.
diff --git a/test/libsolidity/syntaxTests/arrayLength/constant_var.sol b/test/libsolidity/syntaxTests/arrayLength/constant_var.sol
new file mode 100644
index 00000000..41750250
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/constant_var.sol
@@ -0,0 +1,5 @@
+contract C {
+ uint constant LEN = 10;
+ uint[LEN] ids;
+}
+// ---- \ No newline at end of file
diff --git a/test/libsolidity/syntaxTests/arrayLength/cyclic_constant.sol b/test/libsolidity/syntaxTests/arrayLength/cyclic_constant.sol
new file mode 100644
index 00000000..91ba9045
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/cyclic_constant.sol
@@ -0,0 +1,8 @@
+contract C {
+ uint constant LEN = LEN;
+ function f() {
+ uint[LEN] a;
+ }
+}
+// ----
+// TypeError: (37-40): Cyclic constant definition (or maximum recursion depth exhausted).
diff --git a/test/libsolidity/syntaxTests/arrayLength/inline_array.sol b/test/libsolidity/syntaxTests/arrayLength/inline_array.sol
new file mode 100644
index 00000000..a30745d3
--- /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/invalid_expression_1.sol b/test/libsolidity/syntaxTests/arrayLength/invalid_expression_1.sol
new file mode 100644
index 00000000..c92861eb
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/invalid_expression_1.sol
@@ -0,0 +1,5 @@
+contract C {
+ uint[-true] ids;
+}
+// ----
+// TypeError: (22-27): Invalid array length, expected integer literal or constant expression.
diff --git a/test/libsolidity/syntaxTests/arrayLength/invalid_expression_2.sol b/test/libsolidity/syntaxTests/arrayLength/invalid_expression_2.sol
new file mode 100644
index 00000000..92e3c3cf
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/invalid_expression_2.sol
@@ -0,0 +1,5 @@
+contract C {
+ uint[true/1] ids;
+}
+// ----
+// TypeError: (22-28): Invalid array length, expected integer literal or constant expression.
diff --git a/test/libsolidity/syntaxTests/arrayLength/invalid_expression_3.sol b/test/libsolidity/syntaxTests/arrayLength/invalid_expression_3.sol
new file mode 100644
index 00000000..26add45c
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/invalid_expression_3.sol
@@ -0,0 +1,5 @@
+contract C {
+ uint[1/true] ids;
+}
+// ----
+// TypeError: (22-28): Invalid array length, expected integer literal or constant expression.
diff --git a/test/libsolidity/syntaxTests/arrayLength/invalid_expression_4.sol b/test/libsolidity/syntaxTests/arrayLength/invalid_expression_4.sol
new file mode 100644
index 00000000..a0d58f4a
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/invalid_expression_4.sol
@@ -0,0 +1,5 @@
+contract C {
+ uint[1.111111E1111111111111] ids;
+}
+// ----
+// TypeError: (22-44): Invalid array length, expected integer literal or constant expression.
diff --git a/test/libsolidity/syntaxTests/arrayLength/invalid_expression_5.sol b/test/libsolidity/syntaxTests/arrayLength/invalid_expression_5.sol
new file mode 100644
index 00000000..38a80867
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/invalid_expression_5.sol
@@ -0,0 +1,5 @@
+contract C {
+ uint[3/0] ids;
+}
+// ----
+// TypeError: (22-25): Operator / not compatible with types int_const 3 and int_const 0
diff --git a/test/libsolidity/syntaxTests/arrayLength/non_integer_constant_var.sol b/test/libsolidity/syntaxTests/arrayLength/non_integer_constant_var.sol
new file mode 100644
index 00000000..7a853a34
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/non_integer_constant_var.sol
@@ -0,0 +1,6 @@
+contract C {
+ bool constant LEN = true;
+ uint[LEN] ids;
+}
+// ----
+// TypeError: (52-55): Invalid array length, expected integer literal or constant expression.
diff --git a/test/libsolidity/syntaxTests/arrayLength/not_convertible_to_integer.sol b/test/libsolidity/syntaxTests/arrayLength/not_convertible_to_integer.sol
new file mode 100644
index 00000000..b44ccfe9
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/not_convertible_to_integer.sol
@@ -0,0 +1,5 @@
+contract C {
+ uint[true] ids;
+}
+// ----
+// TypeError: (22-26): 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 00000000..40f55ad6
--- /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/pure_functions.sol b/test/libsolidity/syntaxTests/arrayLength/pure_functions.sol
new file mode 100644
index 00000000..b620db76
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/pure_functions.sol
@@ -0,0 +1,6 @@
+contract C {
+ uint constant LEN = keccak256(ripemd160(33));
+ uint[LEN] ids;
+}
+// ----
+// TypeError: (72-75): Invalid array length, expected integer literal or constant expression.
diff --git a/test/libsolidity/syntaxTests/arrayLength/too_large.sol b/test/libsolidity/syntaxTests/arrayLength/too_large.sol
new file mode 100644
index 00000000..c90a7494
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/too_large.sol
@@ -0,0 +1,5 @@
+contract C {
+ uint[8**90] ids;
+}
+// ----
+// TypeError: (22-27): Invalid array length, expected integer literal or constant expression.
diff --git a/test/libsolidity/syntaxTests/arrayLength/tuples.sol b/test/libsolidity/syntaxTests/arrayLength/tuples.sol
new file mode 100644
index 00000000..bc10b3b5
--- /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.