aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2017-03-04 02:26:54 +0800
committerchriseth <c@ethdev.com>2017-03-13 20:30:23 +0800
commit592cec7e9074313e7ce5539769c065ecf5cbba12 (patch)
tree72a26e95183f4356f68e9ae5c02756062a58415d
parent4077e56a2fad49227e7fe4c1ed4ff81462fc6a9a (diff)
downloaddexon-solidity-592cec7e9074313e7ce5539769c065ecf5cbba12.tar
dexon-solidity-592cec7e9074313e7ce5539769c065ecf5cbba12.tar.gz
dexon-solidity-592cec7e9074313e7ce5539769c065ecf5cbba12.tar.bz2
dexon-solidity-592cec7e9074313e7ce5539769c065ecf5cbba12.tar.lz
dexon-solidity-592cec7e9074313e7ce5539769c065ecf5cbba12.tar.xz
dexon-solidity-592cec7e9074313e7ce5539769c065ecf5cbba12.tar.zst
dexon-solidity-592cec7e9074313e7ce5539769c065ecf5cbba12.zip
Disallow constants that are neither value types nor strings.
-rw-r--r--docs/contracts.rst3
-rw-r--r--libsolidity/analysis/TypeChecker.cpp8
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp50
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp20
4 files changed, 55 insertions, 26 deletions
diff --git a/docs/contracts.rst b/docs/contracts.rst
index 52dd440a..f15dc122 100644
--- a/docs/contracts.rst
+++ b/docs/contracts.rst
@@ -433,6 +433,9 @@ assigned a value or expression which is a constant at compile time. The compiler
not reserve a storage slot for these variables and every occurrence is
replaced by their constant value (which might be computed by the optimizer).
+Not all types for constants are implemented at this time. The only supported types are
+value types and strings.
+
::
pragma solidity ^0.4.0;
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp
index 75530739..41636db7 100644
--- a/libsolidity/analysis/TypeChecker.cpp
+++ b/libsolidity/analysis/TypeChecker.cpp
@@ -473,6 +473,14 @@ bool TypeChecker::visit(VariableDeclaration const& _variable)
{
if (!_variable.isStateVariable())
typeError(_variable.location(), "Illegal use of \"constant\" specifier.");
+ if (!_variable.type()->isValueType())
+ {
+ bool allowed = false;
+ if (auto arrayType = dynamic_cast<ArrayType const*>(_variable.type().get()))
+ allowed = arrayType->isString();
+ if (!allowed)
+ typeError(_variable.location(), "Constants of non-value type not yet implemented.");
+ }
if (!_variable.value())
typeError(_variable.location(), "Uninitialized \"constant\" variable.");
else if (!_variable.value()->annotation().isPure)
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index 552352e4..831840e2 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -4576,31 +4576,33 @@ BOOST_AUTO_TEST_CASE(assignment_to_const_var_involving_keccak)
BOOST_CHECK(callContractFunction("f()") == encodeArgs(dev::keccak256("abc")));
}
-BOOST_AUTO_TEST_CASE(assignment_to_const_array_vars)
-{
- char const* sourceCode = R"(
- contract C {
- uint[3] constant x = [uint(1), 2, 3];
- uint constant y = x[0] + x[1] + x[2];
- function f() returns (uint) { return y; }
- }
- )";
- compileAndRun(sourceCode);
- BOOST_CHECK(callContractFunction("f()") == encodeArgs(1 + 2 + 3));
-}
+// Disabled until https://github.com/ethereum/solidity/issues/715 is implemented
+//BOOST_AUTO_TEST_CASE(assignment_to_const_array_vars)
+//{
+// char const* sourceCode = R"(
+// contract C {
+// uint[3] constant x = [uint(1), 2, 3];
+// uint constant y = x[0] + x[1] + x[2];
+// function f() returns (uint) { return y; }
+// }
+// )";
+// compileAndRun(sourceCode);
+// BOOST_CHECK(callContractFunction("f()") == encodeArgs(1 + 2 + 3));
+//}
-BOOST_AUTO_TEST_CASE(constant_struct)
-{
- char const* sourceCode = R"(
- contract C {
- struct S { uint x; uint[] y; }
- S constant x = S(5, new uint[](4));
- function f() returns (uint) { return x.x; }
- }
- )";
- compileAndRun(sourceCode);
- BOOST_CHECK(callContractFunction("f()") == encodeArgs(5));
-}
+// Disabled until https://github.com/ethereum/solidity/issues/715 is implemented
+//BOOST_AUTO_TEST_CASE(constant_struct)
+//{
+// char const* sourceCode = R"(
+// contract C {
+// struct S { uint x; uint[] y; }
+// S constant x = S(5, new uint[](4));
+// function f() returns (uint) { return x.x; }
+// }
+// )";
+// compileAndRun(sourceCode);
+// BOOST_CHECK(callContractFunction("f()") == encodeArgs(5));
+//}
BOOST_AUTO_TEST_CASE(packed_storage_structs_uint)
{
diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index 90831ccd..71fef32d 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -2183,6 +2183,22 @@ BOOST_AUTO_TEST_CASE(assigning_state_to_const_variable)
CHECK_ERROR(text, TypeError, "Initial value for constant variable has to be compile-time constant.");
}
+BOOST_AUTO_TEST_CASE(constant_string_literal_disallows_assignment)
+{
+ char const* text = R"(
+ contract Test {
+ string constant x = "abefghijklmnopqabcdefghijklmnopqabcdefghijklmnopqabca";
+ function f() {
+ x[0] = "f";
+ }
+ }
+ )";
+
+ // Even if this is made possible in the future, we should not allow assignment
+ // to elements of constant arrays.
+ CHECK_ERROR(text, TypeError, "Index access for string is not possible.");
+}
+
BOOST_AUTO_TEST_CASE(assign_constant_function_value_to_constant)
{
char const* text = R"(
@@ -2231,7 +2247,7 @@ BOOST_AUTO_TEST_CASE(assignment_to_const_array_vars)
uint[3] constant x = [uint(1), 2, 3];
}
)";
- CHECK_SUCCESS(text);
+ CHECK_ERROR(text, TypeError, "implemented");
}
BOOST_AUTO_TEST_CASE(constant_struct)
@@ -2242,7 +2258,7 @@ BOOST_AUTO_TEST_CASE(constant_struct)
S constant x = S(5, new uint[](4));
}
)";
- CHECK_SUCCESS(text);
+ CHECK_ERROR(text, TypeError, "implemented");
}
BOOST_AUTO_TEST_CASE(uninitialized_const_variable)