diff options
author | chriseth <c@ethdev.com> | 2015-06-09 20:26:08 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-06-15 20:40:41 +0800 |
commit | 650ed1a3fc9902bba9e389d34dc7d8b9312016df (patch) | |
tree | 3a50e85e926efd870b6bd1d00f0fc06d562ed5b6 | |
parent | 0233cb44fd45c4cd240b3deab01d1e7298c515c3 (diff) | |
download | dexon-solidity-650ed1a3fc9902bba9e389d34dc7d8b9312016df.tar.gz dexon-solidity-650ed1a3fc9902bba9e389d34dc7d8b9312016df.tar.zst dexon-solidity-650ed1a3fc9902bba9e389d34dc7d8b9312016df.zip |
Distinction between storage pointer and storage ref and type checking for conversion between storage and memory.
-rw-r--r-- | libsolidity/SolidityNameAndTypeResolution.cpp | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/libsolidity/SolidityNameAndTypeResolution.cpp b/libsolidity/SolidityNameAndTypeResolution.cpp index 3948a4a2..fced1284 100644 --- a/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/libsolidity/SolidityNameAndTypeResolution.cpp @@ -1889,6 +1889,93 @@ BOOST_AUTO_TEST_CASE(storage_location_local_variables) BOOST_CHECK_NO_THROW(parseTextAndResolveNames(sourceCode)); } +BOOST_AUTO_TEST_CASE(assignment_mem_to_local_storage_variable) +{ + char const* sourceCode = R"( + contract C { + uint[] data; + function f(uint[] x) { + var dataRef = data; + dataRef = x; + } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + +BOOST_AUTO_TEST_CASE(storage_assign_to_different_local_variable) +{ + char const* sourceCode = R"( + contract C { + uint[] data; + uint8[] otherData; + function f() { + uint8[] storage x = otherData; + uint[] storage y = data; + y = x; + // note that data = otherData works + } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + +BOOST_AUTO_TEST_CASE(assignment_mem_storage_variable_directly) +{ + char const* sourceCode = R"( + contract C { + uint[] data; + function f(uint[] x) { + data = x; + } + } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(sourceCode)); +} + +BOOST_AUTO_TEST_CASE(function_argument_mem_to_storage) +{ + char const* sourceCode = R"( + contract C { + function f(uint[] storage x) private { + } + function g(uint[] x) { + f(x); + } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + +BOOST_AUTO_TEST_CASE(function_argument_storage_to_mem) +{ + char const* sourceCode = R"( + contract C { + function f(uint[] storage x) private { + g(x); + } + function g(uint[] x) { + } + } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(sourceCode)); +} + +BOOST_AUTO_TEST_CASE(mem_array_assignment_changes_base_type) +{ + // Such an assignment is possible in storage, but not in memory + // (because it would incur an otherwise unnecessary copy). + // This requirement might be lifted, though. + char const* sourceCode = R"( + contract C { + function f(uint8[] memory x) private { + uint[] memory y = x; + } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() } |