diff options
Diffstat (limited to 'test')
73 files changed, 1361 insertions, 129 deletions
diff --git a/test/ExecutionFramework.cpp b/test/ExecutionFramework.cpp index 00f5e697..ea624735 100644 --- a/test/ExecutionFramework.cpp +++ b/test/ExecutionFramework.cpp @@ -85,6 +85,22 @@ std::pair<bool, string> ExecutionFramework::compareAndCreateMessage( return make_pair(false, message); } +u256 ExecutionFramework::gasLimit() const +{ + auto latestBlock = m_rpc.eth_getBlockByNumber("latest", false); + return u256(latestBlock["gasLimit"].asString()); +} + +u256 ExecutionFramework::gasPrice() const +{ + return u256(m_rpc.eth_gasPrice()); +} + +u256 ExecutionFramework::blockHash(u256 const& _blockNumber) const +{ + return u256(m_rpc.eth_getBlockByNumber(toHex(_blockNumber, HexPrefix::Add), false)["hash"].asString()); +} + void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256 const& _value) { if (m_showMessages) diff --git a/test/ExecutionFramework.h b/test/ExecutionFramework.h index cdbec81d..0b42f9d0 100644 --- a/test/ExecutionFramework.h +++ b/test/ExecutionFramework.h @@ -194,6 +194,13 @@ public: return encodeArgs(u256(0x20), u256(_arg.size()), _arg); } + u256 gasLimit() const; + u256 gasPrice() const; + u256 blockHash(u256 const& _blockNumber) const; + u256 const& blockNumber() const { + return m_blockNumber; + } + private: template <class CppFunction, class... Args> auto callCppAndEncodeResult(CppFunction const& _cppFunction, Args const&... _arguments) diff --git a/test/RPCSession.cpp b/test/RPCSession.cpp index b9b19b2f..9ac24972 100644 --- a/test/RPCSession.cpp +++ b/test/RPCSession.cpp @@ -207,6 +207,11 @@ string RPCSession::eth_getStorageRoot(string const& _address, string const& _blo return rpcCall("eth_getStorageRoot", { quote(address), quote(_blockNumber) }).asString(); } +string RPCSession::eth_gasPrice() +{ + return rpcCall("eth_gasPrice").asString(); +} + void RPCSession::personal_unlockAccount(string const& _address, string const& _password, int _duration) { BOOST_REQUIRE_MESSAGE( diff --git a/test/RPCSession.h b/test/RPCSession.h index 5af2e26a..6e1391b4 100644 --- a/test/RPCSession.h +++ b/test/RPCSession.h @@ -113,6 +113,7 @@ public: std::string eth_sendTransaction(std::string const& _transaction); std::string eth_getBalance(std::string const& _address, std::string const& _blockNumber); std::string eth_getStorageRoot(std::string const& _address, std::string const& _blockNumber); + std::string eth_gasPrice(); std::string personal_newAccount(std::string const& _password); void personal_unlockAccount(std::string const& _address, std::string const& _password, int _duration); void test_setChainParams(std::vector<std::string> const& _accounts); diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh index 7256386d..c9acb99a 100755 --- a/test/cmdlineTests.sh +++ b/test/cmdlineTests.sh @@ -43,18 +43,42 @@ function printError() { echo "$(tput setaf 1)$1$(tput sgr0)"; } function compileFull() { + local expected_exit_code=0 + local expect_output=0 + if [[ $1 = '-e' ]] + then + expected_exit_code=1 + expect_output=1 + shift; + fi + if [[ $1 = '-w' ]] + then + expect_output=1 + shift; + fi + local files="$*" - local output failed + local output + + local stderr_path=$(mktemp) set +e - output=$( ("$SOLC" $FULLARGS $files) 2>&1 ) - failed=$? + "$SOLC" $FULLARGS $files >/dev/null 2>"$stderr_path" + local exit_code=$? + local errors=$(grep -v -E 'Warning: This is a pre-release compiler version|Warning: Experimental features are turned on|pragma experimental ABIEncoderV2|\^-------------------------------\^' < "$stderr_path") set -e + rm "$stderr_path" - if [ $failed -ne 0 ] + if [[ \ + "$exit_code" -ne "$expected_exit_code" || \ + ( $expect_output -eq 0 && -n "$errors" ) || \ + ( $expect_output -ne 0 && -z "$errors" ) \ + ]] then - printError "Compilation failed on:" - echo "$output" + printError "Unexpected compilation result:" + printError "Expected failure: $expected_exit_code - Expected warning / error output: $expect_output" + printError "Was failure: $exit_code" + echo "$errors" printError "While calling:" echo "\"$SOLC\" $FULLARGS $files" printError "Inside directory:" @@ -63,22 +87,6 @@ function compileFull() fi } -function compileWithoutWarning() -{ - local files="$*" - local output failed - - set +e - output=$("$SOLC" $files 2>&1) - failed=$? - # Remove the pre-release warning from the compiler output - output=$(echo "$output" | grep -v 'pre-release') - echo "$output" - set -e - - test -z "$output" -a "$failed" -eq 0 -} - printTask "Testing unknown options..." ( set +e @@ -144,6 +152,10 @@ test_solc_file_input_failures "file_not_found.sol" "" "" "\"file_not_found.sol\" printTask "Testing passing files that are not files..." test_solc_file_input_failures "." "" "" "\".\" is not a valid file." +printTask "Testing passing empty remappings..." +test_solc_file_input_failures "${0}" "=/some/remapping/target" "" "Invalid remapping: \"=/some/remapping/target\"." +test_solc_file_input_failures "${0}" "ctx:=/some/remapping/target" "" "Invalid remapping: \"ctx:=/some/remapping/target\"." + printTask "Compiling various other contracts and libraries..." ( cd "$REPO_ROOT"/test/compilationTests/ @@ -153,7 +165,7 @@ do then echo " - $dir" cd "$dir" - compileFull *.sol */*.sol + compileFull -w *.sol */*.sol cd .. fi done @@ -169,8 +181,25 @@ TMPDIR=$(mktemp -d) "$REPO_ROOT"/scripts/isolate_tests.py "$REPO_ROOT"/docs/ docs for f in *.sol do + # The contributors guide uses syntax tests, but we cannot + # really handle them here. + if grep -E 'DeclarationError:|// ----' "$f" >/dev/null + then + continue + fi echo "$f" - compileFull "$TMPDIR/$f" + opts='' + # We expect errors if explicitly stated, or if imports + # are used (in the style guide) + if grep -E "This will not compile|import \"" "$f" >/dev/null + then + opts="-e" + fi + if grep "This will report a warning" "$f" >/dev/null + then + opts="$opts -w" + fi + compileFull $opts "$TMPDIR/$f" done ) rm -rf "$TMPDIR" diff --git a/test/compilationTests/stringutils/strings.sol b/test/compilationTests/stringutils/strings.sol index 6865664b..f89a2527 100644 --- a/test/compilationTests/stringutils/strings.sol +++ b/test/compilationTests/stringutils/strings.sol @@ -83,23 +83,23 @@ library strings { uint ret; if (self == 0) return 0; - if (self & 0xffffffffffffffffffffffffffffffff == 0) { + if (uint256(self) & 0xffffffffffffffffffffffffffffffff == 0) { ret += 16; self = bytes32(uint(self) / 0x100000000000000000000000000000000); } - if (self & 0xffffffffffffffff == 0) { + if (uint256(self) & 0xffffffffffffffff == 0) { ret += 8; self = bytes32(uint(self) / 0x10000000000000000); } - if (self & 0xffffffff == 0) { + if (uint256(self) & 0xffffffff == 0) { ret += 4; self = bytes32(uint(self) / 0x100000000); } - if (self & 0xffff == 0) { + if (uint256(self) & 0xffff == 0) { ret += 2; self = bytes32(uint(self) / 0x10000); } - if (self & 0xff == 0) { + if (uint256(self) & 0xff == 0) { ret += 1; } return 32 - ret; diff --git a/test/libevmasm/Assembler.cpp b/test/libevmasm/Assembler.cpp new file mode 100644 index 00000000..bc652f56 --- /dev/null +++ b/test/libevmasm/Assembler.cpp @@ -0,0 +1,152 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see <http://www.gnu.org/licenses/>. +*/ +/** + * @author Alex Beregszaszi + * @date 2018 + * Tests for the assembler. + */ + +#include <libdevcore/JSON.h> +#include <libevmasm/Assembly.h> + +#include <boost/test/unit_test.hpp> + +#include <string> +#include <tuple> +#include <memory> + +using namespace std; +using namespace dev::eth; + +namespace dev +{ +namespace solidity +{ +namespace test +{ + +namespace +{ + void checkCompilation(::dev::eth::Assembly const& _assembly) + { + LinkerObject output = _assembly.assemble(); + BOOST_CHECK(output.bytecode.size() > 0); + BOOST_CHECK(output.toHex().length() > 0); + } +} + +BOOST_AUTO_TEST_SUITE(Assembler) + +BOOST_AUTO_TEST_CASE(all_assembly_items) +{ + Assembly _assembly; + _assembly.setSourceLocation(SourceLocation(1, 3, make_shared<string>("root.asm"))); + + Assembly _subAsm; + _subAsm.setSourceLocation(SourceLocation(6, 8, make_shared<string>("sub.asm"))); + _subAsm.append(Instruction::INVALID); + shared_ptr<Assembly> _subAsmPtr = make_shared<Assembly>(_subAsm); + + // Tag + auto tag = _assembly.newTag(); + _assembly.append(tag); + // Operation + _assembly.append(u256(1)); + _assembly.append(u256(2)); + // Push + _assembly.append(Instruction::KECCAK256); + // PushProgramSize + _assembly.appendProgramSize(); + // PushLibraryAddress + _assembly.appendLibraryAddress("someLibrary"); + // PushTag + Operation + _assembly.appendJump(tag); + // PushString + _assembly.append("Unused feature for pushing string"); + // PushData + _assembly.append(bytes{0x1, 0x2, 0x3, 0x4}); + // PushSubSize + auto sub = _assembly.appendSubroutine(_subAsmPtr); + // PushSub + _assembly.pushSubroutineOffset(size_t(sub.data())); + // PushDeployTimeAddress + _assembly.append(PushDeployTimeAddress); + // Operation + _assembly.append(Instruction::STOP); + _assembly.appendAuxiliaryDataToEnd(bytes{0x42, 0x66}); + _assembly.appendAuxiliaryDataToEnd(bytes{0xee, 0xaa}); + + checkCompilation(_assembly); + + BOOST_CHECK_EQUAL( + _assembly.assemble().toHex(), + "5b6001600220606773__someLibrary___________________________" + "6000567f556e75736564206665617475726520666f722070757368696e" + "6720737472696e605f6001605e73000000000000000000000000000000000000000000fe" + "fe010203044266eeaa" + ); + BOOST_CHECK_EQUAL( + _assembly.assemblyString(), + " /* \"root.asm\":1:3 */\n" + "tag_1:\n" + " keccak256(0x2, 0x1)\n" + " bytecodeSize\n" + " linkerSymbol(\"bf005014d9d0f534b8fcb268bd84c491a2380f4acd260d1ccfe9cd8201f7e994\")\n" + " jump(tag_1)\n" + " data_027497964124140851e8a9992ba16b5c1aaf9730b78d6036c8d65e3bb5ea4c8f\n" + " data_a6885b3731702da62e8e4a8f584ac46a7f6822f4e2ba50fba902f67b1588d23b\n" + " dataSize(sub_0)\n" + " dataOffset(sub_0)\n" + " deployTimeAddress()\n" + " stop\n" + "stop\n" + "data_a6885b3731702da62e8e4a8f584ac46a7f6822f4e2ba50fba902f67b1588d23b 01020304\n" + "\n" + "sub_0: assembly {\n" + " /* \"sub.asm\":6:8 */\n" + " invalid\n" + "}\n" + "\n" + "auxdata: 0x4266eeaa\n" + ); + BOOST_CHECK_EQUAL( + dev::jsonCompactPrint(_assembly.assemblyJSON()), + "{\".auxdata\":\"4266eeaa\",\".code\":[{\"begin\":1,\"end\":3,\"name\":\"tag\",\"value\":\"1\"}," + "{\"begin\":1,\"end\":3,\"name\":\"JUMPDEST\"}," + "{\"begin\":1,\"end\":3,\"name\":\"PUSH\",\"value\":\"1\"}," + "{\"begin\":1,\"end\":3,\"name\":\"PUSH\",\"value\":\"2\"}," + "{\"begin\":1,\"end\":3,\"name\":\"KECCAK256\"}," + "{\"begin\":1,\"end\":3,\"name\":\"PUSHSIZE\"}," + "{\"begin\":1,\"end\":3,\"name\":\"PUSHLIB\",\"value\":\"someLibrary\"}," + "{\"begin\":1,\"end\":3,\"name\":\"PUSH [tag]\",\"value\":\"1\"}," + "{\"begin\":1,\"end\":3,\"name\":\"JUMP\"}," + "{\"begin\":1,\"end\":3,\"name\":\"PUSH tag\",\"value\":\"Unused feature for pushing string\"}," + "{\"begin\":1,\"end\":3,\"name\":\"PUSH data\",\"value\":\"A6885B3731702DA62E8E4A8F584AC46A7F6822F4E2BA50FBA902F67B1588D23B\"}," + "{\"begin\":1,\"end\":3,\"name\":\"PUSH #[$]\",\"value\":\"0000000000000000000000000000000000000000000000000000000000000000\"}," + "{\"begin\":1,\"end\":3,\"name\":\"PUSH [$]\",\"value\":\"0000000000000000000000000000000000000000000000000000000000000000\"}," + "{\"begin\":1,\"end\":3,\"name\":\"PUSHDEPLOYADDRESS\"}," + "{\"begin\":1,\"end\":3,\"name\":\"STOP\"}]," + "\".data\":{\"0\":{\".code\":[{\"begin\":6,\"end\":8,\"name\":\"INVALID\"}]}," + "\"A6885B3731702DA62E8E4A8F584AC46A7F6822F4E2BA50FBA902F67B1588D23B\":\"01020304\"}}" + ); +} + +BOOST_AUTO_TEST_SUITE_END() + +} +} +} // end namespaces diff --git a/test/libjulia/Simplifier.cpp b/test/libjulia/Simplifier.cpp index e5b7e0d8..3cc95b7a 100644 --- a/test/libjulia/Simplifier.cpp +++ b/test/libjulia/Simplifier.cpp @@ -139,7 +139,7 @@ BOOST_AUTO_TEST_CASE(mod_and) ); } -BOOST_AUTO_TEST_CASE(not_applied) +BOOST_AUTO_TEST_CASE(not_applied_removes_non_constant_and_not_movable) { CHECK( // The first argument of div is not constant. @@ -149,4 +149,30 @@ BOOST_AUTO_TEST_CASE(not_applied) ); } +BOOST_AUTO_TEST_CASE(not_applied_function_call_different_names) +{ + CHECK( + "{ function f1() -> a { } function f2() -> b {} let c := sub(f1(), f2()) }", + "{ function f1() -> a { } function f2() -> b {} let c := sub(f1(), f2()) }" + ); +} + +BOOST_AUTO_TEST_CASE(not_applied_function_call_different_arguments) +{ + CHECK( + "{ function f(a) -> b { } let c := sub(f(0), f(1)) }", + "{ function f(a) -> b { } let c := sub(f(0), f(1)) }" + ); +} + +BOOST_AUTO_TEST_CASE(not_applied_function_call_equality_not_movable) +{ + CHECK( + // Even if the functions pass the equality check, they are not movable. + "{ function f() -> a { } let b := sub(f(), f()) }", + "{ function f() -> a { } let b := sub(f(), f()) }" + ); +} + + BOOST_AUTO_TEST_SUITE_END() diff --git a/test/libsolidity/ABIDecoderTests.cpp b/test/libsolidity/ABIDecoderTests.cpp index 28f982c4..f91a4f85 100644 --- a/test/libsolidity/ABIDecoderTests.cpp +++ b/test/libsolidity/ABIDecoderTests.cpp @@ -792,8 +792,8 @@ BOOST_AUTO_TEST_CASE(return_dynamic_types_cross_call_advanced) a = "1234567890123456789012345678901234567890"; b = uint(-1); c = new bytes20[](4); - c[0] = bytes20(1234); - c[3] = bytes20(6789); + c[0] = bytes20(uint160(1234)); + c[3] = bytes20(uint160(6789)); d = 0x1234; } function f() public returns (bytes memory, uint, bytes20[] memory, uint) { diff --git a/test/libsolidity/ABIEncoderTests.cpp b/test/libsolidity/ABIEncoderTests.cpp index b1eda425..06cfb4ec 100644 --- a/test/libsolidity/ABIEncoderTests.cpp +++ b/test/libsolidity/ABIEncoderTests.cpp @@ -133,7 +133,7 @@ BOOST_AUTO_TEST_CASE(conversion) int8 c; int16 d; assembly { a := sub(0, 1) c := 0x0101ff d := 0xff01 } - emit E(10, x, a, uint8(b), c, int8(d)); + emit E(bytes4(uint32(10)), x, a, uint8(b), c, int8(d)); } } )"; diff --git a/test/libsolidity/GasMeter.cpp b/test/libsolidity/GasMeter.cpp index 84e30033..4887dd5b 100644 --- a/test/libsolidity/GasMeter.cpp +++ b/test/libsolidity/GasMeter.cpp @@ -122,7 +122,7 @@ BOOST_AUTO_TEST_CASE(non_overlapping_filtered_costs) function f(uint a) public returns (uint b) { x.length = a; for (; a < 200; ++a) { - x[a] = 9; + x[a] = 0x09; b = a * a; } return f(a - 1); diff --git a/test/libsolidity/Imports.cpp b/test/libsolidity/Imports.cpp index df31ac40..dc33d577 100644 --- a/test/libsolidity/Imports.cpp +++ b/test/libsolidity/Imports.cpp @@ -167,7 +167,7 @@ BOOST_AUTO_TEST_CASE(name_clash_in_import) BOOST_AUTO_TEST_CASE(remappings) { CompilerStack c; - c.setRemappings(vector<string>{"s=s_1.4.6", "t=Tee"}); + c.setRemappings(vector<CompilerStack::Remapping>{{"", "s", "s_1.4.6"},{"", "t", "Tee"}}); c.addSource("a", "import \"s/s.sol\"; contract A is S {} pragma solidity >=0.0;"); c.addSource("b", "import \"t/tee.sol\"; contract A is Tee {} pragma solidity >=0.0;"); c.addSource("s_1.4.6/s.sol", "contract S {} pragma solidity >=0.0;"); @@ -179,7 +179,7 @@ BOOST_AUTO_TEST_CASE(remappings) BOOST_AUTO_TEST_CASE(context_dependent_remappings) { CompilerStack c; - c.setRemappings(vector<string>{"a:s=s_1.4.6", "b:s=s_1.4.7"}); + c.setRemappings(vector<CompilerStack::Remapping>{{"a", "s", "s_1.4.6"}, {"b", "s", "s_1.4.7"}}); c.addSource("a/a.sol", "import \"s/s.sol\"; contract A is SSix {} pragma solidity >=0.0;"); c.addSource("b/b.sol", "import \"s/s.sol\"; contract B is SSeven {} pragma solidity >=0.0;"); c.addSource("s_1.4.6/s.sol", "contract SSix {} pragma solidity >=0.0;"); @@ -200,7 +200,11 @@ BOOST_AUTO_TEST_CASE(filename_with_period) BOOST_AUTO_TEST_CASE(context_dependent_remappings_ensure_default_and_module_preserved) { CompilerStack c; - c.setRemappings(vector<string>{"foo=vendor/foo_2.0.0", "vendor/bar:foo=vendor/foo_1.0.0", "bar=vendor/bar"}); + c.setRemappings(vector<CompilerStack::Remapping>{ + {"", "foo", "vendor/foo_2.0.0"}, + {"vendor/bar", "foo", "vendor/foo_1.0.0"}, + {"", "bar", "vendor/bar"} + }); c.addSource("main.sol", "import \"foo/foo.sol\"; import {Bar} from \"bar/bar.sol\"; contract Main is Foo2, Bar {} pragma solidity >=0.0;"); c.addSource("vendor/bar/bar.sol", "import \"foo/foo.sol\"; contract Bar {Foo1 foo;} pragma solidity >=0.0;"); c.addSource("vendor/foo_1.0.0/foo.sol", "contract Foo1 {} pragma solidity >=0.0;"); @@ -212,7 +216,7 @@ BOOST_AUTO_TEST_CASE(context_dependent_remappings_ensure_default_and_module_pres BOOST_AUTO_TEST_CASE(context_dependent_remappings_order_independent) { CompilerStack c; - c.setRemappings(vector<string>{"a:x/y/z=d", "a/b:x=e"}); + c.setRemappings(vector<CompilerStack::Remapping>{{"a", "x/y/z", "d"}, {"a/b", "x", "e"}}); c.addSource("a/main.sol", "import \"x/y/z/z.sol\"; contract Main is D {} pragma solidity >=0.0;"); c.addSource("a/b/main.sol", "import \"x/y/z/z.sol\"; contract Main is E {} pragma solidity >=0.0;"); c.addSource("d/z.sol", "contract D {} pragma solidity >=0.0;"); @@ -220,7 +224,7 @@ BOOST_AUTO_TEST_CASE(context_dependent_remappings_order_independent) c.setEVMVersion(dev::test::Options::get().evmVersion()); BOOST_CHECK(c.compile()); CompilerStack d; - d.setRemappings(vector<string>{"a/b:x=e", "a:x/y/z=d"}); + d.setRemappings(vector<CompilerStack::Remapping>{{"a/b", "x", "e"}, {"a", "x/y/z", "d"}}); d.addSource("a/main.sol", "import \"x/y/z/z.sol\"; contract Main is D {} pragma solidity >=0.0;"); d.addSource("a/b/main.sol", "import \"x/y/z/z.sol\"; contract Main is E {} pragma solidity >=0.0;"); d.addSource("d/z.sol", "contract D {} pragma solidity >=0.0;"); diff --git a/test/libsolidity/LibSolc.cpp b/test/libsolidity/LibSolc.cpp index 9d5ffa27..61e5ebba 100644 --- a/test/libsolidity/LibSolc.cpp +++ b/test/libsolidity/LibSolc.cpp @@ -111,12 +111,12 @@ BOOST_AUTO_TEST_CASE(basic_compilation) BOOST_CHECK(contract["bytecode"].isString()); BOOST_CHECK_EQUAL( dev::test::bytecodeSansMetadata(contract["bytecode"].asString()), - "6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00" + "6080604052348015600f57600080fd5b50603580601d6000396000f3fe6080604052600080fdfe" ); BOOST_CHECK(contract["runtimeBytecode"].isString()); BOOST_CHECK_EQUAL( dev::test::bytecodeSansMetadata(contract["runtimeBytecode"].asString()), - "6080604052600080fd00" + "6080604052600080fdfe" ); BOOST_CHECK(contract["functionHashes"].isObject()); BOOST_CHECK(contract["gasEstimates"].isObject()); @@ -153,12 +153,12 @@ BOOST_AUTO_TEST_CASE(single_compilation) BOOST_CHECK(contract["bytecode"].isString()); BOOST_CHECK_EQUAL( dev::test::bytecodeSansMetadata(contract["bytecode"].asString()), - "6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00" + "6080604052348015600f57600080fd5b50603580601d6000396000f3fe6080604052600080fdfe" ); BOOST_CHECK(contract["runtimeBytecode"].isString()); BOOST_CHECK_EQUAL( dev::test::bytecodeSansMetadata(contract["runtimeBytecode"].asString()), - "6080604052600080fd00" + "6080604052600080fdfe" ); BOOST_CHECK(contract["functionHashes"].isObject()); BOOST_CHECK(contract["gasEstimates"].isObject()); diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index e487f0ae..7b56fa9d 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -1543,6 +1543,92 @@ BOOST_AUTO_TEST_CASE(mapping_local_compound_assignment) ABI_CHECK(callContractFunction("f()"), encodeArgs(byte(42), byte(0), byte(0), byte(21))); } +BOOST_AUTO_TEST_CASE(mapping_internal_argument) +{ + char const* sourceCode = R"( + contract test { + mapping(uint8 => uint8) a; + mapping(uint8 => uint8) b; + function set_internal(mapping(uint8 => uint8) storage m, uint8 key, uint8 value) internal returns (uint8) { + uint8 oldValue = m[key]; + m[key] = value; + return oldValue; + } + function set(uint8 key, uint8 value_a, uint8 value_b) public returns (uint8 old_a, uint8 old_b) { + old_a = set_internal(a, key, value_a); + old_b = set_internal(b, key, value_b); + } + function get(uint8 key) public returns (uint8, uint8) { + return (a[key], b[key]); + } + } + )"; + compileAndRun(sourceCode); + + ABI_CHECK(callContractFunction("set(uint8,uint8,uint8)", byte(1), byte(21), byte(42)), encodeArgs(byte(0), byte(0))); + ABI_CHECK(callContractFunction("get(uint8)", byte(1)), encodeArgs(byte(21), byte(42))); + ABI_CHECK(callContractFunction("set(uint8,uint8,uint8)", byte(1), byte(10), byte(11)), encodeArgs(byte(21), byte(42))); + ABI_CHECK(callContractFunction("get(uint8)", byte(1)), encodeArgs(byte(10), byte(11))); +} + +BOOST_AUTO_TEST_CASE(mapping_array_internal_argument) +{ + char const* sourceCode = R"( + contract test { + mapping(uint8 => uint8)[2] a; + mapping(uint8 => uint8)[2] b; + function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) { + uint8 oldValue1 = m[0][key]; + uint8 oldValue2 = m[1][key]; + m[0][key] = value1; + m[1][key] = value2; + return (oldValue1, oldValue2); + } + function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) { + (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2); + (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2); + } + function get(uint8 key) public returns (uint8, uint8, uint8, uint8) { + return (a[0][key], a[1][key], b[0][key], b[1][key]); + } + } + )"; + compileAndRun(sourceCode); + + ABI_CHECK(callContractFunction("set(uint8,uint8,uint8,uint8,uint8)", byte(1), byte(21), byte(22), byte(42), byte(43)), encodeArgs(byte(0), byte(0), byte(0), byte(0))); + ABI_CHECK(callContractFunction("get(uint8)", byte(1)), encodeArgs(byte(21), byte(22), byte(42), byte(43))); + ABI_CHECK(callContractFunction("set(uint8,uint8,uint8,uint8,uint8)", byte(1), byte(10), byte(30), byte(11), byte(31)), encodeArgs(byte(21), byte(22), byte(42), byte(43))); + ABI_CHECK(callContractFunction("get(uint8)", byte(1)), encodeArgs(byte(10), byte(30), byte(11), byte(31))); +} + +BOOST_AUTO_TEST_CASE(mapping_internal_return) +{ + char const* sourceCode = R"( + contract test { + mapping(uint8 => uint8) a; + mapping(uint8 => uint8) b; + function f() internal returns (mapping(uint8 => uint8) storage r) { + r = a; + r[1] = 42; + r = b; + r[1] = 84; + } + function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) { + f()[2] = 21; + return (a[0], a[1], a[2], b[0], b[1], b[2]); + } + function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) { + mapping(uint8 => uint8) storage m = f(); + m[2] = 17; + return (a[0], a[1], a[2], b[0], b[1], b[2]); + } + } + )"; + compileAndRun(sourceCode); + + ABI_CHECK(callContractFunction("g()"), encodeArgs(byte(0), byte(42), byte(0), byte(0), byte(84), byte (21))); + ABI_CHECK(callContractFunction("h()"), encodeArgs(byte(0), byte(42), byte(0), byte(0), byte(84), byte (17))); +} BOOST_AUTO_TEST_CASE(structs) { @@ -2211,7 +2297,7 @@ BOOST_AUTO_TEST_CASE(log0) char const* sourceCode = R"( contract test { function a() public { - log0(1); + log0(bytes32(uint256(1))); } } )"; @@ -2228,7 +2314,7 @@ BOOST_AUTO_TEST_CASE(log1) char const* sourceCode = R"( contract test { function a() public { - log1(1, 2); + log1(bytes32(uint256(1)), bytes32(uint256(2))); } } )"; @@ -2246,7 +2332,7 @@ BOOST_AUTO_TEST_CASE(log2) char const* sourceCode = R"( contract test { function a() public { - log2(1, 2, 3); + log2(bytes32(uint256(1)), bytes32(uint256(2)), bytes32(uint256(3))); } } )"; @@ -2265,7 +2351,7 @@ BOOST_AUTO_TEST_CASE(log3) char const* sourceCode = R"( contract test { function a() public { - log3(1, 2, 3, 4); + log3(bytes32(uint256(1)), bytes32(uint256(2)), bytes32(uint256(3)), bytes32(uint256(4))); } } )"; @@ -2284,7 +2370,7 @@ BOOST_AUTO_TEST_CASE(log4) char const* sourceCode = R"( contract test { function a() public { - log4(1, 2, 3, 4, 5); + log4(bytes32(uint256(1)), bytes32(uint256(2)), bytes32(uint256(3)), bytes32(uint256(4)), bytes32(uint256(5))); } } )"; @@ -2303,7 +2389,7 @@ BOOST_AUTO_TEST_CASE(log_in_constructor) char const* sourceCode = R"( contract test { constructor() public { - log1(1, 2); + log1(bytes32(uint256(1)), bytes32(uint256(2))); } } )"; @@ -2902,6 +2988,99 @@ BOOST_AUTO_TEST_CASE(gas_and_value_basic) BOOST_REQUIRE(callContractFunction("checkState()") == encodeArgs(false, 20 - 5)); } +BOOST_AUTO_TEST_CASE(gasleft_decrease) +{ + char const* sourceCode = R"( + contract C { + uint v; + function f() public returns (bool) { + uint startGas = gasleft(); + v++; + assert(startGas > gasleft()); + return true; + } + function g() public returns (bool) { + uint startGas = gasleft(); + assert(startGas > gasleft()); + return true; + } + } + )"; + compileAndRun(sourceCode); + ABI_CHECK(callContractFunction("f()"), encodeArgs(true)); + ABI_CHECK(callContractFunction("g()"), encodeArgs(true)); +} + +BOOST_AUTO_TEST_CASE(gaslimit) +{ + char const* sourceCode = R"( + contract C { + function f() public returns (uint) { + return block.gaslimit; + } + } + )"; + compileAndRun(sourceCode); + ABI_CHECK(callContractFunction("f()"), encodeArgs(gasLimit())); +} + +BOOST_AUTO_TEST_CASE(gasprice) +{ + char const* sourceCode = R"( + contract C { + function f() public returns (uint) { + return tx.gasprice; + } + } + )"; + compileAndRun(sourceCode); + ABI_CHECK(callContractFunction("f()"), encodeArgs(gasPrice())); +} + +BOOST_AUTO_TEST_CASE(blockhash) +{ + char const* sourceCode = R"( + contract C { + uint256 counter; + function g() public returns (bool) { counter++; return true; } + function f() public returns (bytes32[] memory r) { + r = new bytes32[](259); + for (uint i = 0; i < 259; i++) + r[i] = blockhash(block.number - 257 + i); + } + } + )"; + compileAndRun(sourceCode); + // generate a sufficient amount of blocks + while (blockNumber() < u256(255)) + ABI_CHECK(callContractFunction("g()"), encodeArgs(true)); + + vector<u256> hashes; + // currently the test only works for pre-constantinople + if (Options::get().evmVersion() < EVMVersion::constantinople()) + { + // ``blockhash()`` is only valid for the last 256 blocks, otherwise zero + hashes.emplace_back(0); + for (u256 i = blockNumber() - u256(255); i <= blockNumber(); i++) + hashes.emplace_back(blockHash(i)); + // the current block hash is not yet known at execution time and therefore zero + hashes.emplace_back(0); + // future block hashes are zero + hashes.emplace_back(0); + } + else + // TODO: Starting from constantinople blockhash always seems to return zero. + // The blockhash contract introduced in EIP96 seems to break in our setup of + // aleth (setting the constantinople fork block to zero and resetting the chain + // to block zero before each test run). Pre-deploying the blockchain contract + // during genesis seems to help, but currently causes problems with other tests. + // Set the expectation to zero for now, so that this test tracks changes in this + // behavior. + hashes.assign(259, 0); + + ABI_CHECK(callContractFunction("f()"), encodeDyn(hashes)); +} + BOOST_AUTO_TEST_CASE(value_complex) { char const* sourceCode = R"( @@ -4576,6 +4755,68 @@ BOOST_AUTO_TEST_CASE(constructing_enums_from_ints) ABI_CHECK(callContractFunction("test()"), encodeArgs(1)); } +BOOST_AUTO_TEST_CASE(struct_referencing) +{ + static char const* sourceCode = R"( + pragma experimental ABIEncoderV2; + interface I { + struct S { uint a; } + } + library L { + struct S { uint b; uint a; } + function f() public pure returns (S) { + S memory s; + s.a = 3; + return s; + } + function g() public pure returns (I.S) { + I.S memory s; + s.a = 4; + return s; + } + // argument-dependant lookup tests + function a(I.S memory) public pure returns (uint) { return 1; } + function a(S memory) public pure returns (uint) { return 2; } + } + contract C is I { + function f() public pure returns (S) { + S memory s; + s.a = 1; + return s; + } + function g() public pure returns (I.S) { + I.S memory s; + s.a = 2; + return s; + } + function h() public pure returns (L.S) { + L.S memory s; + s.a = 5; + return s; + } + function x() public pure returns (L.S) { + return L.f(); + } + function y() public pure returns (I.S) { + return L.g(); + } + function a1() public pure returns (uint) { S memory s; return L.a(s); } + function a2() public pure returns (uint) { L.S memory s; return L.a(s); } + } + )"; + compileAndRun(sourceCode, 0, "L"); + ABI_CHECK(callContractFunction("f()"), encodeArgs(0, 3)); + ABI_CHECK(callContractFunction("g()"), encodeArgs(4)); + compileAndRun(sourceCode, 0, "C", bytes(), map<string, Address>{ {"L", m_contractAddress}}); + ABI_CHECK(callContractFunction("f()"), encodeArgs(1)); + ABI_CHECK(callContractFunction("g()"), encodeArgs(2)); + ABI_CHECK(callContractFunction("h()"), encodeArgs(0, 5)); + ABI_CHECK(callContractFunction("x()"), encodeArgs(0, 3)); + ABI_CHECK(callContractFunction("y()"), encodeArgs(4)); + ABI_CHECK(callContractFunction("a1()"), encodeArgs(1)); + ABI_CHECK(callContractFunction("a2()"), encodeArgs(2)); +} + BOOST_AUTO_TEST_CASE(enum_referencing) { char const* sourceCode = R"( @@ -5017,7 +5258,7 @@ BOOST_AUTO_TEST_CASE(array_copy_target_simple) function test() public returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e) { for (uint i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i)); - data2[8] = data2[9] = 2; + data2[8] = data2[9] = bytes8(uint64(2)); data2 = data1; a = data2[1]; b = data2[2]; @@ -5076,10 +5317,10 @@ BOOST_AUTO_TEST_CASE(array_copy_target_leftover2) bytes8[4] data1; // fits into one slot bytes10[6] data2; // 4 elements need two slots function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) { - data1[0] = 1; - data1[1] = 2; - data1[2] = 3; - data1[3] = 4; + data1[0] = bytes8(uint64(1)); + data1[1] = bytes8(uint64(2)); + data1[2] = bytes8(uint64(3)); + data1[3] = bytes8(uint64(4)); for (uint i = 0; i < data2.length; ++i) data2[i] = bytes10(uint80(0xffff00 | (1 + i))); data2 = data1; @@ -5274,13 +5515,13 @@ BOOST_AUTO_TEST_CASE(byte_array_push) contract c { bytes data; function test() public returns (bool x) { - if (data.push(5) != 1) return true; - if (data[0] != 5) return true; - data.push(4); - if (data[1] != 4) return true; - uint l = data.push(3); - if (data[2] != 3) return true; - if (l != 3) return true; + if (data.push(0x05) != 1) return true; + if (data[0] != 0x05) return true; + data.push(0x04); + if (data[1] != 0x04) return true; + uint l = data.push(0x03); + if (data[2] != 0x03) return true; + if (l != 0x03) return true; } } )"; @@ -5453,11 +5694,11 @@ BOOST_AUTO_TEST_CASE(byte_array_pop) contract c { bytes data; function test() public returns (uint x, uint y, uint l) { - data.push(7); - x = data.push(3); + data.push(0x07); + x = data.push(0x03); data.pop(); data.pop(); - y = data.push(2); + y = data.push(0x02); l = data.length; } } @@ -5490,9 +5731,9 @@ BOOST_AUTO_TEST_CASE(byte_array_pop_storage_empty) contract c { bytes data; function test() public { - data.push(7); - data.push(5); - data.push(3); + data.push(0x07); + data.push(0x05); + data.push(0x03); data.pop(); data.pop(); data.pop(); @@ -5538,7 +5779,7 @@ BOOST_AUTO_TEST_CASE(byte_array_pop_long_storage_empty_garbage_ref) bytes data; function test() public { for (uint8 i = 0; i <= 40; i++) - data.push(3); + data.push(0x03); for (uint8 j = 0; j <= 40; j++) { assembly { mstore(0, "garbage") @@ -5560,7 +5801,7 @@ BOOST_AUTO_TEST_CASE(byte_array_pop_masking_long) bytes data; function test() public returns (bytes memory) { for (uint i = 0; i < 34; i++) - data.push(3); + data.push(0x03); data.pop(); return data; } @@ -5582,7 +5823,7 @@ BOOST_AUTO_TEST_CASE(byte_array_pop_copy_long) bytes data; function test() public returns (bytes memory) { for (uint i = 0; i < 33; i++) - data.push(3); + data.push(0x03); for (uint j = 0; j < 4; j++) data.pop(); return data; @@ -5672,10 +5913,10 @@ BOOST_AUTO_TEST_CASE(bytes_index_access) data[31] = 0x77; data[32] = 0x14; - data[31] = 1; - data[31] |= 8; - data[30] = 1; - data[32] = 3; + data[31] = 0x01; + data[31] |= 0x08; + data[30] = 0x01; + data[32] = 0x03; return uint(uint8(data[30])) * 0x100 | uint(uint8(data[31])) * 0x10 | uint(uint8(data[32])); } } @@ -5703,7 +5944,7 @@ BOOST_AUTO_TEST_CASE(bytes_delete_element) delete data[94]; delete data[96]; delete data[98]; - return data[94] == 0 && data[95] == 95 && data[96] == 0 && data[97] == 97; + return data[94] == 0 && uint8(data[95]) == 95 && data[96] == 0 && uint8(data[97]) == 97; } } )"; @@ -6060,19 +6301,19 @@ BOOST_AUTO_TEST_CASE(packed_storage_structs_bytes) s2 data; byte y; function test() public returns (bool) { - x = 1; - data.a = 2; - data.inner.a = 3; - data.inner.b = 4; + x = 0x01; + data.a = 0x02; + data.inner.a = 0x03; + data.inner.b = 0x04; data.inner.c = "1234567890"; data.inner.d = "123456789"; data.inner.e = "abcdefghij"; - data.b = 5; - data.c = 6; - y = 7; - return x == 1 && data.a == 2 && data.inner.a == 3 && data.inner.b == 4 && + data.b = 0x05; + data.c = byte(0x06); + y = 0x07; + return x == 0x01 && data.a == 0x02 && data.inner.a == 0x03 && data.inner.b == 0x04 && data.inner.c == "1234567890" && data.inner.d == "123456789" && - data.inner.e == "abcdefghij" && data.b == 5 && data.c == 6 && y == 7; + data.inner.e == "abcdefghij" && data.b == 0x05 && data.c == byte(0x06) && y == 0x07; } } )"; @@ -7961,6 +8202,162 @@ BOOST_AUTO_TEST_CASE(internal_types_in_library) ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(4), u256(17))); } +BOOST_AUTO_TEST_CASE(mapping_arguments_in_library) +{ + char const* sourceCode = R"( + library Lib { + function set(mapping(uint => uint) storage m, uint key, uint value) internal + { + m[key] = value; + } + function get(mapping(uint => uint) storage m, uint key) internal view returns (uint) + { + return m[key]; + } + } + contract Test { + mapping(uint => uint) m; + function set(uint256 key, uint256 value) public returns (uint) + { + uint oldValue = Lib.get(m, key); + Lib.set(m, key, value); + return oldValue; + } + function get(uint256 key) public view returns (uint) { + return Lib.get(m, key); + } + } + )"; + compileAndRun(sourceCode, 0, "Lib"); + compileAndRun(sourceCode, 0, "Test", bytes(), map<string, Address>{{"Lib", m_contractAddress}}); + ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(1), u256(42)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(2), u256(84)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(21), u256(7)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("get(uint256)", u256(0)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("get(uint256)", u256(1)), encodeArgs(u256(42))); + ABI_CHECK(callContractFunction("get(uint256)", u256(2)), encodeArgs(u256(84))); + ABI_CHECK(callContractFunction("get(uint256)", u256(21)), encodeArgs(u256(7))); + ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(1), u256(21)), encodeArgs(u256(42))); + ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(2), u256(42)), encodeArgs(u256(84))); + ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(21), u256(14)), encodeArgs(u256(7))); + ABI_CHECK(callContractFunction("get(uint256)", u256(0)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("get(uint256)", u256(1)), encodeArgs(u256(21))); + ABI_CHECK(callContractFunction("get(uint256)", u256(2)), encodeArgs(u256(42))); + ABI_CHECK(callContractFunction("get(uint256)", u256(21)), encodeArgs(u256(14))); +} + +BOOST_AUTO_TEST_CASE(mapping_returns_in_library) +{ + char const* sourceCode = R"( + library Lib { + function choose_mapping(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) internal pure returns(mapping(uint=>uint) storage) + { + return c ? a : b; + } + } + contract Test { + mapping(uint => uint) a; + mapping(uint => uint) b; + function set(bool choice, uint256 key, uint256 value) public returns (uint) + { + mapping(uint => uint) storage m = Lib.choose_mapping(a, b, choice); + uint oldValue = m[key]; + m[key] = value; + return oldValue; + } + function get(bool choice, uint256 key) public view returns (uint) { + return Lib.choose_mapping(a, b, choice)[key]; + } + function get_a(uint256 key) public view returns (uint) { + return a[key]; + } + function get_b(uint256 key) public view returns (uint) { + return b[key]; + } + } + )"; + compileAndRun(sourceCode, 0, "Lib"); + compileAndRun(sourceCode, 0, "Test", bytes(), map<string, Address>{{"Lib", m_contractAddress}}); + ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(1), u256(42)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(2), u256(84)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(21), u256(7)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", false, u256(1), u256(10)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", false, u256(2), u256(11)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", false, u256(21), u256(12)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(0)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(1)), encodeArgs(u256(42))); + ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(2)), encodeArgs(u256(84))); + ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(21)), encodeArgs(u256(7))); + ABI_CHECK(callContractFunction("get_a(uint256)", u256(0)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("get_a(uint256)", u256(1)), encodeArgs(u256(42))); + ABI_CHECK(callContractFunction("get_a(uint256)", u256(2)), encodeArgs(u256(84))); + ABI_CHECK(callContractFunction("get_a(uint256)", u256(21)), encodeArgs(u256(7))); + ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(0)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(1)), encodeArgs(u256(10))); + ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(2)), encodeArgs(u256(11))); + ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(21)), encodeArgs(u256(12))); + ABI_CHECK(callContractFunction("get_b(uint256)", u256(0)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("get_b(uint256)", u256(1)), encodeArgs(u256(10))); + ABI_CHECK(callContractFunction("get_b(uint256)", u256(2)), encodeArgs(u256(11))); + ABI_CHECK(callContractFunction("get_b(uint256)", u256(21)), encodeArgs(u256(12))); + ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(1), u256(21)), encodeArgs(u256(42))); + ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(2), u256(42)), encodeArgs(u256(84))); + ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(21), u256(14)), encodeArgs(u256(7))); + ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", false, u256(1), u256(30)), encodeArgs(u256(10))); + ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", false, u256(2), u256(31)), encodeArgs(u256(11))); + ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", false, u256(21), u256(32)), encodeArgs(u256(12))); + ABI_CHECK(callContractFunction("get_a(uint256)", u256(0)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("get_a(uint256)", u256(1)), encodeArgs(u256(21))); + ABI_CHECK(callContractFunction("get_a(uint256)", u256(2)), encodeArgs(u256(42))); + ABI_CHECK(callContractFunction("get_a(uint256)", u256(21)), encodeArgs(u256(14))); + ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(0)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(1)), encodeArgs(u256(21))); + ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(2)), encodeArgs(u256(42))); + ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(21)), encodeArgs(u256(14))); + ABI_CHECK(callContractFunction("get_b(uint256)", u256(0)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("get_b(uint256)", u256(1)), encodeArgs(u256(30))); + ABI_CHECK(callContractFunction("get_b(uint256)", u256(2)), encodeArgs(u256(31))); + ABI_CHECK(callContractFunction("get_b(uint256)", u256(21)), encodeArgs(u256(32))); + ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(0)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(1)), encodeArgs(u256(30))); + ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(2)), encodeArgs(u256(31))); + ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(21)), encodeArgs(u256(32))); +} + +BOOST_AUTO_TEST_CASE(mapping_returns_in_library_named) +{ + char const* sourceCode = R"( + library Lib { + function f(mapping(uint => uint) storage a, mapping(uint => uint) storage b) internal returns(mapping(uint=>uint) storage r) + { + r = a; + r[1] = 42; + r = b; + r[1] = 21; + } + } + contract Test { + mapping(uint => uint) a; + mapping(uint => uint) b; + function f() public returns (uint, uint, uint, uint, uint, uint) + { + Lib.f(a, b)[2] = 84; + return (a[0], a[1], a[2], b[0], b[1], b[2]); + } + function g() public returns (uint, uint, uint, uint, uint, uint) + { + mapping(uint => uint) storage m = Lib.f(a, b); + m[2] = 17; + return (a[0], a[1], a[2], b[0], b[1], b[2]); + } + } + )"; + compileAndRun(sourceCode, 0, "Lib"); + compileAndRun(sourceCode, 0, "Test", bytes(), map<string, Address>{{"Lib", m_contractAddress}}); + ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(0), u256(42), u256(0), u256(0), u256(21), u256(84))); + ABI_CHECK(callContractFunction("g()"), encodeArgs(u256(0), u256(42), u256(0), u256(0), u256(21), u256(17))); +} + BOOST_AUTO_TEST_CASE(using_library_structs) { char const* sourceCode = R"( @@ -8062,17 +8459,17 @@ BOOST_AUTO_TEST_CASE(short_strings) if (data1[4] != "4") return 11; for (uint i = 0; i < data1.length; i ++) data1[i] = byte(uint8(i * 3)); - if (data1[4] != 4 * 3) return 12; - if (data1[67] != 67 * 3) return 13; + if (uint8(data1[4]) != 4 * 3) return 12; + if (uint8(data1[67]) != 67 * 3) return 13; // change length: long -> short data1.length = 22; if (data1.length != 22) return 14; - if (data1[21] != byte(21 * 3)) return 15; - if (data1[2] != 2 * 3) return 16; + if (uint8(data1[21]) != 21 * 3) return 15; + if (uint8(data1[2]) != 2 * 3) return 16; // change length: short -> shorter data1.length = 19; if (data1.length != 19) return 17; - if (data1[7] != byte(7 * 3)) return 18; + if (uint8(data1[7]) != 7 * 3) return 18; // and now again to original size data1.length = 22; if (data1.length != 22) return 19; @@ -8888,7 +9285,7 @@ BOOST_AUTO_TEST_CASE(fixed_bytes_length_access) contract C { byte a; function f(bytes32 x) public returns (uint, uint, uint) { - return (x.length, bytes16(2).length, a.length + 7); + return (x.length, bytes16(uint128(2)).length, a.length + 7); } } )"; @@ -9383,9 +9780,9 @@ BOOST_AUTO_TEST_CASE(iszero_bnot_correct) char const* sourceCode = R"( contract C { function f() public returns (bool) { - bytes32 x = 1; + bytes32 x = bytes32(uint256(1)); assembly { x := not(x) } - if (x != ~bytes32(1)) return false; + if (x != ~bytes32(uint256(1))) return false; assembly { x := iszero(x) } if (x != bytes32(0)) return false; return true; @@ -9404,7 +9801,7 @@ BOOST_AUTO_TEST_CASE(cleanup_bytes_types) function f(bytes2 a, uint16 x) public returns (uint) { if (a != "ab") return 1; if (x != 0x0102) return 2; - if (bytes3(uint24(x)) != 0x0102) return 3; + if (bytes3(uint24(x)) != 0x000102) return 3; return 0; } } @@ -9736,7 +10133,7 @@ BOOST_AUTO_TEST_CASE(failing_ecrecover_invalid_input) char const* sourceCode = R"( contract C { function f() public returns (address) { - return ecrecover(bytes32(uint(-1)), 1, 2, 3); + return ecrecover(bytes32(uint(-1)), 1, bytes32(uint(2)), bytes32(uint(3))); } } )"; @@ -9754,8 +10151,8 @@ BOOST_AUTO_TEST_CASE(failing_ecrecover_invalid_input_proper) 0, // invalid v value 0x6944c77849b18048f6abe0db8084b0d0d0689cdddb53d2671c36967b58691ad4, 0xef4f06ba4f78319baafd0424365777241af4dfd3da840471b4b4b087b7750d0d, - 0x00ca35b7d915458ef540ade6068dfe2f44e8fa733c, - 0x00ca35b7d915458ef540ade6068dfe2f44e8fa733c + 0x000000000000000000000000ca35b7d915458ef540ade6068dfe2f44e8fa733c, + 0x000000000000000000000000ca35b7d915458ef540ade6068dfe2f44e8fa733c ); } function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s, uint blockExpired, bytes32 salt) diff --git a/test/libsolidity/SolidityTypes.cpp b/test/libsolidity/SolidityTypes.cpp index db0e3b66..e171d974 100644 --- a/test/libsolidity/SolidityTypes.cpp +++ b/test/libsolidity/SolidityTypes.cpp @@ -195,11 +195,11 @@ BOOST_AUTO_TEST_CASE(type_identifiers) TupleType t({e.type(), s.type(), stringArray, nullptr}); BOOST_CHECK_EQUAL(t.identifier(), "t_tuple$_t_type$_t_enum$_Enum_$4_$_$_t_type$_t_struct$_Struct_$3_storage_ptr_$_$_t_array$_t_string_storage_$20_storage_ptr_$__$"); - TypePointer sha3fun = make_shared<FunctionType>(strings{}, strings{}, FunctionType::Kind::SHA3); - BOOST_CHECK_EQUAL(sha3fun->identifier(), "t_function_sha3_nonpayable$__$returns$__$"); + TypePointer keccak256fun = make_shared<FunctionType>(strings{}, strings{}, FunctionType::Kind::KECCAK256); + BOOST_CHECK_EQUAL(keccak256fun->identifier(), "t_function_keccak256_nonpayable$__$returns$__$"); - FunctionType metaFun(TypePointers{sha3fun}, TypePointers{s.type()}); - BOOST_CHECK_EQUAL(metaFun.identifier(), "t_function_internal_nonpayable$_t_function_sha3_nonpayable$__$returns$__$_$returns$_t_type$_t_struct$_Struct_$3_storage_ptr_$_$"); + FunctionType metaFun(TypePointers{keccak256fun}, TypePointers{s.type()}); + BOOST_CHECK_EQUAL(metaFun.identifier(), "t_function_internal_nonpayable$_t_function_keccak256_nonpayable$__$returns$__$_$returns$_t_type$_t_struct$_Struct_$3_storage_ptr_$_$"); TypePointer m = make_shared<MappingType>(Type::fromElementaryTypeName("bytes32"), s.type()); MappingType m2(Type::fromElementaryTypeName("uint64"), m); diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index 16921a24..3aa1dc24 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -238,7 +238,7 @@ BOOST_AUTO_TEST_CASE(basic_compilation) "settings": { "outputSelection": { "fileA": { - "A": [ "abi", "devdoc", "userdoc", "evm.bytecode", "evm.assembly", "evm.gasEstimates", "metadata" ], + "A": [ "abi", "devdoc", "userdoc", "evm.bytecode", "evm.assembly", "evm.gasEstimates", "evm.legacyAssembly", "metadata" ], "": [ "legacyAST" ] } } @@ -261,7 +261,7 @@ BOOST_AUTO_TEST_CASE(basic_compilation) BOOST_CHECK(contract["evm"]["bytecode"]["object"].isString()); BOOST_CHECK_EQUAL( dev::test::bytecodeSansMetadata(contract["evm"]["bytecode"]["object"].asString()), - "6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00" + "6080604052348015600f57600080fd5b50603580601d6000396000f3fe6080604052600080fdfe" ); BOOST_CHECK(contract["evm"]["assembly"].isString()); BOOST_CHECK(contract["evm"]["assembly"].asString().find( @@ -280,6 +280,34 @@ BOOST_AUTO_TEST_CASE(basic_compilation) dev::jsonCompactPrint(contract["evm"]["gasEstimates"]), "{\"creation\":{\"codeDepositCost\":\"10600\",\"executionCost\":\"66\",\"totalCost\":\"10666\"}}" ); + // Lets take the top level `.code` section (the "deployer code"), that should expose most of the features of + // the assembly JSON. What we want to check here is Operation, Push, PushTag, PushSub, PushSubSize and Tag. + BOOST_CHECK(contract["evm"]["legacyAssembly"].isObject()); + BOOST_CHECK(contract["evm"]["legacyAssembly"][".code"].isArray()); + BOOST_CHECK_EQUAL( + dev::jsonCompactPrint(contract["evm"]["legacyAssembly"][".code"]), + "[{\"begin\":0,\"end\":14,\"name\":\"PUSH\",\"value\":\"80\"}," + "{\"begin\":0,\"end\":14,\"name\":\"PUSH\",\"value\":\"40\"}," + "{\"begin\":0,\"end\":14,\"name\":\"MSTORE\"}," + "{\"begin\":0,\"end\":14,\"name\":\"CALLVALUE\"}," + "{\"begin\":8,\"end\":17,\"name\":\"DUP1\"}," + "{\"begin\":5,\"end\":7,\"name\":\"ISZERO\"}," + "{\"begin\":5,\"end\":7,\"name\":\"PUSH [tag]\",\"value\":\"1\"}," + "{\"begin\":5,\"end\":7,\"name\":\"JUMPI\"}," + "{\"begin\":30,\"end\":31,\"name\":\"PUSH\",\"value\":\"0\"}," + "{\"begin\":27,\"end\":28,\"name\":\"DUP1\"}," + "{\"begin\":20,\"end\":32,\"name\":\"REVERT\"}," + "{\"begin\":5,\"end\":7,\"name\":\"tag\",\"value\":\"1\"}," + "{\"begin\":5,\"end\":7,\"name\":\"JUMPDEST\"}," + "{\"begin\":0,\"end\":14,\"name\":\"POP\"}," + "{\"begin\":0,\"end\":14,\"name\":\"PUSH #[$]\",\"value\":\"0000000000000000000000000000000000000000000000000000000000000000\"}," + "{\"begin\":0,\"end\":14,\"name\":\"DUP1\"}," + "{\"begin\":0,\"end\":14,\"name\":\"PUSH [$]\",\"value\":\"0000000000000000000000000000000000000000000000000000000000000000\"}," + "{\"begin\":0,\"end\":14,\"name\":\"PUSH\",\"value\":\"0\"}," + "{\"begin\":0,\"end\":14,\"name\":\"CODECOPY\"}," + "{\"begin\":0,\"end\":14,\"name\":\"PUSH\",\"value\":\"0\"}," + "{\"begin\":0,\"end\":14,\"name\":\"RETURN\"}]" + ); BOOST_CHECK(contract["metadata"].isString()); BOOST_CHECK(dev::test::isValidMetadata(contract["metadata"].asString())); BOOST_CHECK(result["sources"].isObject()); diff --git a/test/libsolidity/syntaxTests/controlFlow/mappingReturn/named_err.sol b/test/libsolidity/syntaxTests/controlFlow/mappingReturn/named_err.sol new file mode 100644 index 00000000..35420b6d --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/mappingReturn/named_err.sol @@ -0,0 +1,5 @@ +contract C { + function f() internal pure returns (mapping(uint=>uint) storage r) { } +} +// ---- +// TypeError: (53-82): This variable is of storage pointer type and might be returned without assignment and could be used uninitialized. Assign the variable (potentially from itself) to fix this error. diff --git a/test/libsolidity/syntaxTests/controlFlow/mappingReturn/named_fine.sol b/test/libsolidity/syntaxTests/controlFlow/mappingReturn/named_fine.sol new file mode 100644 index 00000000..4146192f --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/mappingReturn/named_fine.sol @@ -0,0 +1,5 @@ +contract C { + mapping(uint=>uint) m; + function f() internal view returns (mapping(uint=>uint) storage r) { r = m; } +} +// ---- diff --git a/test/libsolidity/syntaxTests/controlFlow/mappingReturn/unnamed_err.sol b/test/libsolidity/syntaxTests/controlFlow/mappingReturn/unnamed_err.sol new file mode 100644 index 00000000..7e8c4501 --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/mappingReturn/unnamed_err.sol @@ -0,0 +1,5 @@ +contract C { + function f() internal pure returns (mapping(uint=>uint) storage) {} +} +// ---- +// TypeError: (53-72): This variable is of storage pointer type and might be returned without assignment and could be used uninitialized. Assign the variable (potentially from itself) to fix this error. diff --git a/test/libsolidity/syntaxTests/controlFlow/mappingReturn/unnamed_fine.sol b/test/libsolidity/syntaxTests/controlFlow/mappingReturn/unnamed_fine.sol new file mode 100644 index 00000000..9c5e3149 --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/mappingReturn/unnamed_fine.sol @@ -0,0 +1,5 @@ +contract C { + mapping(uint=>uint) m; + function f() internal view returns (mapping(uint=>uint) storage) { return m; } +} +// ---- diff --git a/test/libsolidity/syntaxTests/conversion/conversion_to_bytes.sol b/test/libsolidity/syntaxTests/conversion/conversion_to_bytes.sol new file mode 100644 index 00000000..5946e921 --- /dev/null +++ b/test/libsolidity/syntaxTests/conversion/conversion_to_bytes.sol @@ -0,0 +1,5 @@ +contract test { + function f() public pure returns (bytes) { + return bytes("abc"); + } +} diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/161_warns_assigning_decimal_to_bytesxx.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/161_warns_assigning_decimal_to_bytesxx.sol deleted file mode 100644 index 957322af..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/161_warns_assigning_decimal_to_bytesxx.sol +++ /dev/null @@ -1,5 +0,0 @@ -contract Foo { - bytes32 a = 7; -} -// ---- -// Warning: (31-32): Decimal literal assigned to bytesXX variable will be left-aligned. Use an explicit conversion to silence this warning. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/162_does_not_warn_assigning_hex_number_to_bytesxx.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/162_does_not_warn_assigning_hex_number_to_bytesxx.sol deleted file mode 100644 index bc32580a..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/162_does_not_warn_assigning_hex_number_to_bytesxx.sol +++ /dev/null @@ -1,3 +0,0 @@ -contract Foo { - bytes32 a = 0x1234; -} diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/163_explicit_conversion_from_decimal_to_bytesxx.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/163_explicit_conversion_from_decimal_to_bytesxx.sol deleted file mode 100644 index af921869..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/163_explicit_conversion_from_decimal_to_bytesxx.sol +++ /dev/null @@ -1,3 +0,0 @@ -contract Foo { - bytes32 a = bytes32(7); -} diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/186_invalid_utf8_explicit.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/186_invalid_utf8_explicit.sol index 401c46e2..0f67460f 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/186_invalid_utf8_explicit.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/186_invalid_utf8_explicit.sol @@ -2,4 +2,4 @@ contract C { string s = string("\xa0\x00"); } // ---- -// TypeError: (28-46): Explicit type conversion not allowed from "literal_string (contains invalid UTF-8 sequence at position 0)" to "string storage pointer". +// TypeError: (28-46): Explicit type conversion not allowed from "literal_string (contains invalid UTF-8 sequence at position 0)" to "string memory". diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/419_interface_structs.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/419_interface_structs.sol index c74d52d3..385ed18e 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/419_interface_structs.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/419_interface_structs.sol @@ -1,9 +1,6 @@ interface I { struct A { - // This is currently expected to break, but it *may* change in the future. int dummy; } } // ---- -// TypeError: (18-136): Structs cannot be defined in interfaces. -// TypeError: (120-129): Variables cannot be declared in interfaces. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/482_explicit_literal_to_unspecified_string.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/482_explicit_literal_to_unspecified_string.sol index a83eee72..c44fab55 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/482_explicit_literal_to_unspecified_string.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/482_explicit_literal_to_unspecified_string.sol @@ -4,4 +4,4 @@ contract C { } } // ---- -// TypeError: (52-65): Explicit type conversion not allowed from "literal_string "abc"" to "string storage pointer". +// Warning: (52-65): Statement has no effect. diff --git a/test/libsolidity/syntaxTests/specialFunctions/encodePacked_array_of_structs.sol b/test/libsolidity/syntaxTests/specialFunctions/encodePacked_array_of_structs.sol new file mode 100644 index 00000000..036e108a --- /dev/null +++ b/test/libsolidity/syntaxTests/specialFunctions/encodePacked_array_of_structs.sol @@ -0,0 +1,9 @@ +contract C { + struct S { uint x; } + function f() public pure { + S[] memory s; + abi.encodePacked(s); + } +} +// ---- +// TypeError: (116-117): This type cannot be encoded. diff --git a/test/libsolidity/syntaxTests/specialFunctions/encode_array_of_struct.sol b/test/libsolidity/syntaxTests/specialFunctions/encode_array_of_struct.sol new file mode 100644 index 00000000..7a4d8250 --- /dev/null +++ b/test/libsolidity/syntaxTests/specialFunctions/encode_array_of_struct.sol @@ -0,0 +1,10 @@ +pragma experimental ABIEncoderV2; +contract C { + struct S { uint x; } + function f() public pure { + S[] memory s; + abi.encode(s); + } +} +// ---- +// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. diff --git a/test/libsolidity/syntaxTests/types/bytesm.sol b/test/libsolidity/syntaxTests/types/bytesm.sol index 550760b9..77ff7524 100644 --- a/test/libsolidity/syntaxTests/types/bytesm.sol +++ b/test/libsolidity/syntaxTests/types/bytesm.sol @@ -1,5 +1,5 @@ contract C { - byte b = byte(1); + byte b = byte(0x01); bytes1 b1 = b; bytes2 b2 = b1; bytes3 b3 = b2; diff --git a/test/libsolidity/syntaxTests/types/decimal_literal_to_bytesXX_explicit.sol b/test/libsolidity/syntaxTests/types/decimal_literal_to_bytesXX_explicit.sol new file mode 100644 index 00000000..ff285a07 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/decimal_literal_to_bytesXX_explicit.sol @@ -0,0 +1,23 @@ +contract C { + function f() public pure { + bytes1 b1 = bytes1(1); + bytes2 b2 = bytes2(1); + bytes2 b3 = bytes2(256); + bytes3 b4 = bytes3(1); + bytes3 b5 = bytes3(65536); + bytes4 b6 = bytes4(1); + bytes4 b7 = bytes4(16777216); + bytes16 b8 = bytes16(1); + bytes32 b9 = bytes32(1); + } +} +// ---- +// TypeError: (60-69): Explicit type conversion not allowed from "int_const 1" to "bytes1". +// TypeError: (88-97): Explicit type conversion not allowed from "int_const 1" to "bytes2". +// TypeError: (116-127): Explicit type conversion not allowed from "int_const 256" to "bytes2". +// TypeError: (146-155): Explicit type conversion not allowed from "int_const 1" to "bytes3". +// TypeError: (174-187): Explicit type conversion not allowed from "int_const 65536" to "bytes3". +// TypeError: (206-215): Explicit type conversion not allowed from "int_const 1" to "bytes4". +// TypeError: (234-250): Explicit type conversion not allowed from "int_const 16777216" to "bytes4". +// TypeError: (270-280): Explicit type conversion not allowed from "int_const 1" to "bytes16". +// TypeError: (300-310): Explicit type conversion not allowed from "int_const 1" to "bytes32". diff --git a/test/libsolidity/syntaxTests/types/decimal_literal_to_bytesXX_implicit.sol b/test/libsolidity/syntaxTests/types/decimal_literal_to_bytesXX_implicit.sol new file mode 100644 index 00000000..e472c43b --- /dev/null +++ b/test/libsolidity/syntaxTests/types/decimal_literal_to_bytesXX_implicit.sol @@ -0,0 +1,23 @@ +contract C { + function f() public pure { + bytes1 b1 = 1; + bytes2 b2 = 1; + bytes2 b3 = 256; + bytes3 b4 = 1; + bytes3 b5 = 65536; + bytes4 b6 = 1; + bytes4 b7 = 16777216; + bytes16 b8 = 1; + bytes32 b9 = 1; + } +} +// ---- +// TypeError: (48-61): Type int_const 1 is not implicitly convertible to expected type bytes1. +// TypeError: (68-81): Type int_const 1 is not implicitly convertible to expected type bytes2. +// TypeError: (88-103): Type int_const 256 is not implicitly convertible to expected type bytes2. +// TypeError: (110-123): Type int_const 1 is not implicitly convertible to expected type bytes3. +// TypeError: (130-147): Type int_const 65536 is not implicitly convertible to expected type bytes3. +// TypeError: (154-167): Type int_const 1 is not implicitly convertible to expected type bytes4. +// TypeError: (174-194): Type int_const 16777216 is not implicitly convertible to expected type bytes4. +// TypeError: (201-215): Type int_const 1 is not implicitly convertible to expected type bytes16. +// TypeError: (222-236): Type int_const 1 is not implicitly convertible to expected type bytes32. diff --git a/test/libsolidity/syntaxTests/types/function_types/function_parameter_return_types_fail.sol b/test/libsolidity/syntaxTests/types/function_types/function_parameter_return_types_fail.sol new file mode 100644 index 00000000..0d4fded1 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/function_types/function_parameter_return_types_fail.sol @@ -0,0 +1,42 @@ +contract Test +{ + function uint256_to_uint256(uint256 x) internal pure returns (uint256) { return x; } + function uint256_to_string(uint256 x) internal pure returns (string memory) { return x == 0 ? "a" : "b"; } + function uint256_to_string_storage(uint256) internal pure returns (string storage); + function string_to_uint256(string memory x) internal pure returns (uint256) { return bytes(x).length; } + function string_to_string(string memory x) internal pure returns (string memory) { return x; } + + function uint256_uint256_to_uint256(uint256 x, uint256 y) internal pure returns (uint256) { return x + y; } + function uint256_uint256_to_string(uint256 x, uint256 y) internal pure returns (string memory) { return x == y ? "a" : "b"; } + function string_uint256_to_string(string memory x, uint256 y) internal pure returns (string memory) { return y == 0 ? "a" : x; } + function string_string_to_string(string memory x, string memory y) internal pure returns (string memory) { return bytes(x).length == 0 ? y : x; } + function uint256_string_to_string(uint256 x, string memory y) internal pure returns (string memory) { return x == 0 ? "a" : y; } + + function tests() internal pure + { + function (uint256) internal pure returns (uint256) var_uint256_to_uint256 = uint256_to_string; + function (uint256) internal pure returns (string memory) var_uint256_to_string = uint256_to_string_storage; + function (string memory) internal pure returns (uint256) var_string_to_uint256 = uint256_to_string; + function (string memory) internal pure returns (string memory) var_string_to_string = var_uint256_to_string; + + function (uint256, uint256) internal pure returns (uint256) var_uint256_uint256_to_uint256 = uint256_to_uint256; + function (string memory, uint256) internal pure returns (string memory) var_string_uint256_to_string = string_to_string; + function (string memory, string memory) internal pure returns (string memory) var_string_string_to_string = string_to_string; + + var_uint256_to_uint256(1); + var_uint256_to_string(2); + var_string_to_uint256("a"); + var_string_to_string("b"); + var_uint256_uint256_to_uint256(3, 4); + var_string_uint256_to_string("c", 7); + var_string_string_to_string("d", "e"); + } +} +// ---- +// TypeError: (1218-1311): Type function (uint256) pure returns (string memory) is not implicitly convertible to expected type function (uint256) pure returns (uint256). +// TypeError: (1319-1425): Type function (uint256) pure returns (string storage pointer) is not implicitly convertible to expected type function (uint256) pure returns (string memory). +// TypeError: (1433-1531): Type function (uint256) pure returns (string memory) is not implicitly convertible to expected type function (string memory) pure returns (uint256). +// TypeError: (1539-1646): Type function (uint256) pure returns (string memory) is not implicitly convertible to expected type function (string memory) pure returns (string memory). +// TypeError: (1655-1766): Type function (uint256) pure returns (uint256) is not implicitly convertible to expected type function (uint256,uint256) pure returns (uint256). +// TypeError: (1774-1893): Type function (string memory) pure returns (string memory) is not implicitly convertible to expected type function (string memory,uint256) pure returns (string memory). +// TypeError: (1901-2025): Type function (string memory) pure returns (string memory) is not implicitly convertible to expected type function (string memory,string memory) pure returns (string memory). diff --git a/test/libsolidity/syntaxTests/types/function_types/function_parameter_return_types_success.sol b/test/libsolidity/syntaxTests/types/function_types/function_parameter_return_types_success.sol new file mode 100644 index 00000000..f750632e --- /dev/null +++ b/test/libsolidity/syntaxTests/types/function_types/function_parameter_return_types_success.sol @@ -0,0 +1,39 @@ +contract Test +{ + function uint256_to_uint256(uint256 x) internal pure returns (uint256) { return x; } + function uint256_to_string(uint256 x) internal pure returns (string memory) { return x == 0 ? "a" : "b"; } + function string_to_uint256(string memory x) internal pure returns (uint256) { return bytes(x).length; } + function string_to_string(string memory x) internal pure returns (string memory) { return x; } + + function uint256_uint256_to_uint256(uint256 x, uint256 y) internal pure returns (uint256) { return x + y; } + function uint256_uint256_to_string(uint256 x, uint256 y) internal pure returns (string memory) { return x == y ? "a" : "b"; } + function string_uint256_to_string(string memory x, uint256 y) internal pure returns (string memory) { return y == 0 ? "a" : x; } + function string_string_to_string(string memory x, string memory y) internal pure returns (string memory) { return bytes(x).length == 0 ? y : x; } + function uint256_string_to_string(uint256 x, string memory y) internal pure returns (string memory) { return x == 0 ? "a" : y; } + + function tests() internal pure + { + function (uint256) internal pure returns (uint256) var_uint256_to_uint256 = uint256_to_uint256; + function (uint256) internal pure returns (string memory) var_uint256_to_string = uint256_to_string; + function (string memory) internal pure returns (uint256) var_string_to_uint256 = string_to_uint256; + function (string memory) internal pure returns (string memory) var_string_to_string = string_to_string; + + function (uint256, uint256) internal pure returns (uint256) var_uint256_uint256_to_uint256 = uint256_uint256_to_uint256; + function (uint256, uint256) internal pure returns (string memory) var_uint256_uint256_to_string = uint256_uint256_to_string; + function (string memory, uint256) internal pure returns (string memory) var_string_uint256_to_string = string_uint256_to_string; + function (string memory, string memory) internal pure returns (string memory) var_string_string_to_string = string_string_to_string; + function (uint256, string memory) internal pure returns (string memory) var_uint256_string_to_string = uint256_string_to_string; + + // Avoid unused variable warnings: + var_uint256_to_uint256(1); + var_uint256_to_string(2); + var_string_to_uint256("a"); + var_string_to_string("b"); + var_uint256_uint256_to_uint256(3, 4); + var_uint256_uint256_to_string(5, 6); + var_string_uint256_to_string("c", 7); + var_string_string_to_string("d", "e"); + var_uint256_string_to_string(8, "f"); + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/types/function_types/function_state_mutability_fail.sol b/test/libsolidity/syntaxTests/types/function_types/function_state_mutability_fail.sol new file mode 100644 index 00000000..818d7840 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/function_types/function_state_mutability_fail.sol @@ -0,0 +1,51 @@ +contract Test +{ + function internalPureFunc(uint256 x) internal pure returns (uint256) { return x; } + function internalViewFunc(uint256 x) internal view returns (uint256) { return x; } + function internalMutableFunc(uint256 x) internal returns (uint256) { return x; } + + function externalPureFunc(uint256 x) external pure returns (uint256) { return x; } + function externalViewFunc(uint256 x) external view returns (uint256) { return x; } + function externalPayableFunc(uint256 x) external payable returns (uint256) { return x; } + function externalMutableFunc(uint256 x) external returns (uint256) { return x; } + + function funcTakesInternalPure(function(uint256) internal pure returns(uint256) a) internal returns (uint256) { return a(4); } + function funcTakesInternalView(function(uint256) internal view returns(uint256) a) internal returns (uint256) { return a(4); } + function funcTakesInternalMutable(function(uint256) internal returns(uint256) a) internal returns (uint256) { return a(4); } + + function funcTakesExternalPure(function(uint256) external pure returns(uint256) a) internal returns (uint256) { return a(4); } + function funcTakesExternalView(function(uint256) external view returns(uint256) a) internal returns (uint256) { return a(4); } + function funcTakesExternalPayable(function(uint256) external payable returns(uint256) a) internal returns (uint256) { return a(4); } + function funcTakesExternalMutable(function(uint256) external returns(uint256) a) internal returns (uint256) { return a(4); } + + function tests() internal + { + funcTakesInternalPure(internalViewFunc); // view -> pure should fail + funcTakesInternalPure(internalMutableFunc); // mutable -> pure should fail + + funcTakesInternalView(internalMutableFunc); // mutable -> view should fail + + funcTakesExternalPure(this.externalViewFunc); // view -> pure should fail + funcTakesExternalPure(this.externalPayableFunc); // payable -> pure should fail + funcTakesExternalPure(this.externalMutableFunc); // mutable -> pure should fail + + funcTakesExternalView(this.externalPayableFunc); // payable -> view should fail + funcTakesExternalView(this.externalMutableFunc); // mutable -> view should fail + + funcTakesExternalPayable(this.externalPureFunc); // pure -> payable should fail + funcTakesExternalPayable(this.externalViewFunc); // view -> payable should fail + funcTakesExternalPayable(this.externalMutableFunc); // mutable -> payable should fail + } +} +// ---- +// TypeError: (1580-1596): Invalid type for argument in function call. Invalid implicit conversion from function (uint256) view returns (uint256) to function (uint256) pure returns (uint256) requested. +// TypeError: (1653-1672): Invalid type for argument in function call. Invalid implicit conversion from function (uint256) returns (uint256) to function (uint256) pure returns (uint256) requested. +// TypeError: (1733-1752): Invalid type for argument in function call. Invalid implicit conversion from function (uint256) returns (uint256) to function (uint256) view returns (uint256) requested. +// TypeError: (1813-1834): Invalid type for argument in function call. Invalid implicit conversion from function (uint256) view external returns (uint256) to function (uint256) pure external returns (uint256) requested. +// TypeError: (1891-1915): Invalid type for argument in function call. Invalid implicit conversion from function (uint256) payable external returns (uint256) to function (uint256) pure external returns (uint256) requested. +// TypeError: (1975-1999): Invalid type for argument in function call. Invalid implicit conversion from function (uint256) external returns (uint256) to function (uint256) pure external returns (uint256) requested. +// TypeError: (2060-2084): Invalid type for argument in function call. Invalid implicit conversion from function (uint256) payable external returns (uint256) to function (uint256) view external returns (uint256) requested. +// TypeError: (2144-2168): Invalid type for argument in function call. Invalid implicit conversion from function (uint256) external returns (uint256) to function (uint256) view external returns (uint256) requested. +// TypeError: (2232-2253): Invalid type for argument in function call. Invalid implicit conversion from function (uint256) pure external returns (uint256) to function (uint256) payable external returns (uint256) requested. +// TypeError: (2316-2337): Invalid type for argument in function call. Invalid implicit conversion from function (uint256) view external returns (uint256) to function (uint256) payable external returns (uint256) requested. +// TypeError: (2400-2424): Invalid type for argument in function call. Invalid implicit conversion from function (uint256) external returns (uint256) to function (uint256) payable external returns (uint256) requested. diff --git a/test/libsolidity/syntaxTests/types/function_types/function_state_mutability_success.sol b/test/libsolidity/syntaxTests/types/function_types/function_state_mutability_success.sol new file mode 100644 index 00000000..4ee515fc --- /dev/null +++ b/test/libsolidity/syntaxTests/types/function_types/function_state_mutability_success.sol @@ -0,0 +1,46 @@ +contract Test +{ + uint y; + function internalPureFunc(uint256 x) internal pure returns (uint256) { return x; } + function internalViewFunc(uint256 x) internal view returns (uint256) { return x + y; } + function internalMutableFunc(uint256 x) internal returns (uint256) { y = x; return x; } + + function externalPureFunc(uint256 x) external pure returns (uint256) { return x; } + function externalViewFunc(uint256 x) external view returns (uint256) { return x + y; } + function externalPayableFunc(uint256 x) external payable returns (uint256) { return x + y; } + function externalMutableFunc(uint256 x) external returns (uint256) { y = x; return x; } + + function funcTakesInternalPure(function(uint256) internal pure returns(uint256) a) internal pure returns (uint256) { return a(4); } + function funcTakesInternalView(function(uint256) internal view returns(uint256) a) internal view returns (uint256) { return a(4); } + function funcTakesInternalMutable(function(uint256) internal returns(uint256) a) internal returns (uint256) { return a(4); } + + function funcTakesExternalPure(function(uint256) external pure returns(uint256) a) internal pure returns (uint256) { return a(4); } + function funcTakesExternalView(function(uint256) external view returns(uint256) a) internal view returns (uint256) { return a(4); } + function funcTakesExternalPayable(function(uint256) external payable returns(uint256) a) internal returns (uint256) { return a(4); } + function funcTakesExternalMutable(function(uint256) external returns(uint256) a) internal returns (uint256) { return a(4); } + + function tests() internal + { + funcTakesInternalPure(internalPureFunc); + + funcTakesInternalView(internalPureFunc); + funcTakesInternalView(internalViewFunc); + + funcTakesInternalMutable(internalPureFunc); + funcTakesInternalMutable(internalViewFunc); + funcTakesInternalMutable(internalMutableFunc); + + funcTakesExternalPure(this.externalPureFunc); + + funcTakesExternalView(this.externalPureFunc); + funcTakesExternalView(this.externalViewFunc); + + funcTakesExternalPayable(this.externalPayableFunc); + + funcTakesExternalMutable(this.externalPureFunc); + funcTakesExternalMutable(this.externalViewFunc); + funcTakesExternalMutable(this.externalPayableFunc); + funcTakesExternalMutable(this.externalMutableFunc); + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/types/hex_literal_to_bytesXX_different_size_explicit.sol b/test/libsolidity/syntaxTests/types/hex_literal_to_bytesXX_different_size_explicit.sol new file mode 100644 index 00000000..e1e9850d --- /dev/null +++ b/test/libsolidity/syntaxTests/types/hex_literal_to_bytesXX_different_size_explicit.sol @@ -0,0 +1,31 @@ +contract C { + function f() public pure { + bytes1 b1 = bytes1(0x1); + bytes1 b2 = bytes1(0x100); + bytes2 b3 = bytes2(0xFF); + bytes2 b4 = bytes2(0x100); + bytes2 b5 = bytes2(0x10000); + bytes3 b6 = bytes3(0xFFFF); + bytes3 b7 = bytes3(0x10000); + bytes3 b8 = bytes3(0x1000000); + bytes4 b9 = bytes4(0xFFFFFF); + bytes4 b10 = bytes4(0x1000000); + bytes4 b11 = bytes4(0x100000000); + bytes16 b12 = bytes16(0x1); + bytes32 b13 = bytes32(0x1); + } +} +// ---- +// TypeError: (60-71): Explicit type conversion not allowed from "int_const 1" to "bytes1". +// TypeError: (90-103): Explicit type conversion not allowed from "int_const 256" to "bytes1". +// TypeError: (122-134): Explicit type conversion not allowed from "int_const 255" to "bytes2". +// TypeError: (153-166): Explicit type conversion not allowed from "int_const 256" to "bytes2". +// TypeError: (185-200): Explicit type conversion not allowed from "int_const 65536" to "bytes2". +// TypeError: (219-233): Explicit type conversion not allowed from "int_const 65535" to "bytes3". +// TypeError: (252-267): Explicit type conversion not allowed from "int_const 65536" to "bytes3". +// TypeError: (286-303): Explicit type conversion not allowed from "int_const 16777216" to "bytes3". +// TypeError: (322-338): Explicit type conversion not allowed from "int_const 16777215" to "bytes4". +// TypeError: (358-375): Explicit type conversion not allowed from "int_const 16777216" to "bytes4". +// TypeError: (395-414): Explicit type conversion not allowed from "int_const 4294967296" to "bytes4". +// TypeError: (435-447): Explicit type conversion not allowed from "int_const 1" to "bytes16". +// TypeError: (468-480): Explicit type conversion not allowed from "int_const 1" to "bytes32". diff --git a/test/libsolidity/syntaxTests/types/hex_literal_to_bytesXX_different_size_implicit.sol b/test/libsolidity/syntaxTests/types/hex_literal_to_bytesXX_different_size_implicit.sol new file mode 100644 index 00000000..44ed9318 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/hex_literal_to_bytesXX_different_size_implicit.sol @@ -0,0 +1,31 @@ +contract C { + function f() public pure { + bytes1 b1 = 0x1; + bytes1 b2 = 0x100; + bytes2 b3 = 0xFF; + bytes2 b4 = 0x100; + bytes2 b5 = 0x10000; + bytes3 b6 = 0xFFFF; + bytes3 b7 = 0x10000; + bytes3 b8 = 0x1000000; + bytes4 b9 = 0xFFFFFF; + bytes4 b10 = 0x1000000; + bytes4 b11 = 0x100000000; + bytes16 b12 = 0x1; + bytes32 b13 = 0x1; + } +} +// ---- +// TypeError: (48-63): Type int_const 1 is not implicitly convertible to expected type bytes1. +// TypeError: (70-87): Type int_const 256 is not implicitly convertible to expected type bytes1. +// TypeError: (94-110): Type int_const 255 is not implicitly convertible to expected type bytes2. +// TypeError: (117-134): Type int_const 256 is not implicitly convertible to expected type bytes2. +// TypeError: (141-160): Type int_const 65536 is not implicitly convertible to expected type bytes2. +// TypeError: (167-185): Type int_const 65535 is not implicitly convertible to expected type bytes3. +// TypeError: (192-211): Type int_const 65536 is not implicitly convertible to expected type bytes3. +// TypeError: (218-239): Type int_const 16777216 is not implicitly convertible to expected type bytes3. +// TypeError: (246-266): Type int_const 16777215 is not implicitly convertible to expected type bytes4. +// TypeError: (273-295): Type int_const 16777216 is not implicitly convertible to expected type bytes4. +// TypeError: (302-326): Type int_const 4294967296 is not implicitly convertible to expected type bytes4. +// TypeError: (333-350): Type int_const 1 is not implicitly convertible to expected type bytes16. +// TypeError: (357-374): Type int_const 1 is not implicitly convertible to expected type bytes32. diff --git a/test/libsolidity/syntaxTests/types/hex_literal_to_bytesXX_same_size_explicit.sol b/test/libsolidity/syntaxTests/types/hex_literal_to_bytesXX_same_size_explicit.sol new file mode 100644 index 00000000..4e18640c --- /dev/null +++ b/test/libsolidity/syntaxTests/types/hex_literal_to_bytesXX_same_size_explicit.sol @@ -0,0 +1,13 @@ +contract C { + function f() public pure { + bytes1 b1 = bytes1(0x01); + bytes1 b2 = bytes1(0xFF); + bytes2 b3 = bytes2(0x0100); + bytes2 b4 = bytes2(0xFFFF); + bytes3 b5 = bytes3(0x010000); + bytes3 b6 = bytes3(0xFFFFFF); + bytes4 b7 = bytes4(0x01000000); + bytes4 b8 = bytes4(0xFFFFFFFF); + b1; b2; b3; b4; b5; b6; b7; b8; + } +} diff --git a/test/libsolidity/syntaxTests/types/hex_literal_to_bytesXX_same_size_implicit.sol b/test/libsolidity/syntaxTests/types/hex_literal_to_bytesXX_same_size_implicit.sol new file mode 100644 index 00000000..daf0bf56 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/hex_literal_to_bytesXX_same_size_implicit.sol @@ -0,0 +1,13 @@ +contract C { + function f() public pure { + bytes1 b1 = 0x01; + bytes1 b2 = 0xFF; + bytes2 b3 = 0x0100; + bytes2 b4 = 0xFFFF; + bytes3 b5 = 0x010000; + bytes3 b6 = 0xFFFFFF; + bytes4 b7 = 0x01000000; + bytes4 b8 = 0xFFFFFFFF; + b1; b2; b3; b4; b5; b6; b7; b8; + } +} diff --git a/test/libsolidity/syntaxTests/types/mapping/argument_external.sol b/test/libsolidity/syntaxTests/types/mapping/argument_external.sol new file mode 100644 index 00000000..0354893f --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/argument_external.sol @@ -0,0 +1,7 @@ +contract C { + function f(mapping(uint => uint) storage) external pure { + } +} +// ---- +// TypeError: (28-49): Type is required to live outside storage. +// TypeError: (28-49): Internal or recursive type is not allowed for public or external functions. diff --git a/test/libsolidity/syntaxTests/types/mapping/argument_internal.sol b/test/libsolidity/syntaxTests/types/mapping/argument_internal.sol new file mode 100644 index 00000000..3c021515 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/argument_internal.sol @@ -0,0 +1,5 @@ +contract C { + function f(mapping(uint => uint) storage) internal pure { + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/types/mapping/argument_private.sol b/test/libsolidity/syntaxTests/types/mapping/argument_private.sol new file mode 100644 index 00000000..63733d71 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/argument_private.sol @@ -0,0 +1,5 @@ +contract C { + function f(mapping(uint => uint) storage) private pure { + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/types/mapping/argument_public.sol b/test/libsolidity/syntaxTests/types/mapping/argument_public.sol new file mode 100644 index 00000000..e4121c7f --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/argument_public.sol @@ -0,0 +1,7 @@ +contract C { + function f(mapping(uint => uint) storage) public pure { + } +} +// ---- +// TypeError: (28-49): Type is required to live outside storage. +// TypeError: (28-49): Internal or recursive type is not allowed for public or external functions. diff --git a/test/libsolidity/syntaxTests/types/mapping/array_argument_external.sol b/test/libsolidity/syntaxTests/types/mapping/array_argument_external.sol new file mode 100644 index 00000000..8dea6907 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/array_argument_external.sol @@ -0,0 +1,6 @@ +contract C { + function f(mapping(uint => uint)[] storage) external pure { + } +} +// ---- +// TypeError: (28-51): Location has to be calldata for external functions (remove the "memory" or "storage" keyword). diff --git a/test/libsolidity/syntaxTests/types/mapping/array_argument_internal.sol b/test/libsolidity/syntaxTests/types/mapping/array_argument_internal.sol new file mode 100644 index 00000000..352d0982 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/array_argument_internal.sol @@ -0,0 +1,5 @@ +contract C { + function f(mapping(uint => uint)[] storage) internal pure { + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/types/mapping/array_argument_private.sol b/test/libsolidity/syntaxTests/types/mapping/array_argument_private.sol new file mode 100644 index 00000000..332dbe6c --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/array_argument_private.sol @@ -0,0 +1,5 @@ +contract C { + function f(mapping(uint => uint)[] storage) private pure { + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/types/mapping/array_argument_public.sol b/test/libsolidity/syntaxTests/types/mapping/array_argument_public.sol new file mode 100644 index 00000000..69dcec01 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/array_argument_public.sol @@ -0,0 +1,6 @@ +contract C { + function f(mapping(uint => uint)[] storage) public pure { + } +} +// ---- +// TypeError: (28-51): Location has to be memory for publicly visible functions (remove the "storage" or "calldata" keyword). diff --git a/test/libsolidity/syntaxTests/types/mapping/function_type_argument_external.sol b/test/libsolidity/syntaxTests/types/mapping/function_type_argument_external.sol new file mode 100644 index 00000000..7fe74fb6 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/function_type_argument_external.sol @@ -0,0 +1,6 @@ +contract C { + function f(function(mapping(uint=>uint) storage) external) public pure { + } +} +// ---- +// TypeError: (37-56): Internal type cannot be used for external function type. diff --git a/test/libsolidity/syntaxTests/types/mapping/function_type_argument_internal.sol b/test/libsolidity/syntaxTests/types/mapping/function_type_argument_internal.sol new file mode 100644 index 00000000..01e2322e --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/function_type_argument_internal.sol @@ -0,0 +1,4 @@ +contract C { + function f(function(mapping(uint=>uint) storage) internal) internal pure { + } +} diff --git a/test/libsolidity/syntaxTests/types/mapping/function_type_return_external.sol b/test/libsolidity/syntaxTests/types/mapping/function_type_return_external.sol new file mode 100644 index 00000000..f0f8dea6 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/function_type_return_external.sol @@ -0,0 +1,6 @@ +contract C { + function f(function() external returns (mapping(uint=>uint) storage)) public pure { + } +} +// ---- +// TypeError: (57-76): Internal type cannot be used for external function type. diff --git a/test/libsolidity/syntaxTests/types/mapping/function_type_return_internal.sol b/test/libsolidity/syntaxTests/types/mapping/function_type_return_internal.sol new file mode 100644 index 00000000..bd298e5d --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/function_type_return_internal.sol @@ -0,0 +1,4 @@ +contract C { + function f(function() internal returns (mapping(uint=>uint) storage)) internal pure { + } +} diff --git a/test/libsolidity/syntaxTests/types/mapping/library_argument_external.sol b/test/libsolidity/syntaxTests/types/mapping/library_argument_external.sol new file mode 100644 index 00000000..e78c6930 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/library_argument_external.sol @@ -0,0 +1,6 @@ +library L { + function f(mapping(uint => uint) storage) external pure { + } +} +// ---- +// TypeError: (27-48): Type is required to live outside storage. diff --git a/test/libsolidity/syntaxTests/types/mapping/library_argument_internal.sol b/test/libsolidity/syntaxTests/types/mapping/library_argument_internal.sol new file mode 100644 index 00000000..1228b6b6 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/library_argument_internal.sol @@ -0,0 +1,4 @@ +library L { + function f(mapping(uint => uint) storage) internal pure { + } +} diff --git a/test/libsolidity/syntaxTests/types/mapping/library_argument_private.sol b/test/libsolidity/syntaxTests/types/mapping/library_argument_private.sol new file mode 100644 index 00000000..5eaff16b --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/library_argument_private.sol @@ -0,0 +1,4 @@ +library L { + function f(mapping(uint => uint) storage) private pure { + } +} diff --git a/test/libsolidity/syntaxTests/types/mapping/library_argument_public.sol b/test/libsolidity/syntaxTests/types/mapping/library_argument_public.sol new file mode 100644 index 00000000..56393b68 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/library_argument_public.sol @@ -0,0 +1,6 @@ +library L { + function f(mapping(uint => uint) storage) public pure { + } +} +// ---- +// TypeError: (27-48): Type is required to live outside storage. diff --git a/test/libsolidity/syntaxTests/types/mapping/library_array_argument_external.sol b/test/libsolidity/syntaxTests/types/mapping/library_array_argument_external.sol new file mode 100644 index 00000000..f5691675 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/library_array_argument_external.sol @@ -0,0 +1,6 @@ +library L { + function f(mapping(uint => uint)[] storage) external pure { + } +} +// ---- +// TypeError: (27-50): Type is required to live outside storage. diff --git a/test/libsolidity/syntaxTests/types/mapping/library_array_argument_internal.sol b/test/libsolidity/syntaxTests/types/mapping/library_array_argument_internal.sol new file mode 100644 index 00000000..55c1cea0 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/library_array_argument_internal.sol @@ -0,0 +1,4 @@ +library L { + function f(mapping(uint => uint)[] storage) internal pure { + } +} diff --git a/test/libsolidity/syntaxTests/types/mapping/library_array_argument_private.sol b/test/libsolidity/syntaxTests/types/mapping/library_array_argument_private.sol new file mode 100644 index 00000000..d37d6504 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/library_array_argument_private.sol @@ -0,0 +1,4 @@ +library L { + function f(mapping(uint => uint)[] storage) private pure { + } +} diff --git a/test/libsolidity/syntaxTests/types/mapping/library_array_argument_public.sol b/test/libsolidity/syntaxTests/types/mapping/library_array_argument_public.sol new file mode 100644 index 00000000..bb06d4bc --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/library_array_argument_public.sol @@ -0,0 +1,6 @@ +library L { + function f(mapping(uint => uint)[] storage) public pure { + } +} +// ---- +// TypeError: (27-50): Type is required to live outside storage. diff --git a/test/libsolidity/syntaxTests/types/mapping/library_return_external.sol b/test/libsolidity/syntaxTests/types/mapping/library_return_external.sol new file mode 100644 index 00000000..a3bb1c32 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/library_return_external.sol @@ -0,0 +1,10 @@ +library L +{ + function f(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) external pure returns(mapping(uint => uint) storage) { + return c ? a : b; + } +} +// ---- +// TypeError: (27-58): Type is required to live outside storage. +// TypeError: (60-91): Type is required to live outside storage. +// TypeError: (123-144): Type is required to live outside storage. diff --git a/test/libsolidity/syntaxTests/types/mapping/library_return_internal.sol b/test/libsolidity/syntaxTests/types/mapping/library_return_internal.sol new file mode 100644 index 00000000..d0fca6bf --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/library_return_internal.sol @@ -0,0 +1,6 @@ +library L +{ + function f(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) internal pure returns(mapping(uint => uint) storage) { + return c ? a : b; + } +} diff --git a/test/libsolidity/syntaxTests/types/mapping/library_return_private.sol b/test/libsolidity/syntaxTests/types/mapping/library_return_private.sol new file mode 100644 index 00000000..13c2000f --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/library_return_private.sol @@ -0,0 +1,6 @@ +library L +{ + function f(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) private pure returns(mapping(uint => uint) storage) { + return c ? a : b; + } +} diff --git a/test/libsolidity/syntaxTests/types/mapping/library_return_public.sol b/test/libsolidity/syntaxTests/types/mapping/library_return_public.sol new file mode 100644 index 00000000..ac52d677 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/library_return_public.sol @@ -0,0 +1,10 @@ +library L +{ + function f(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) public pure returns(mapping(uint => uint) storage) { + return c ? a : b; + } +} +// ---- +// TypeError: (27-58): Type is required to live outside storage. +// TypeError: (60-91): Type is required to live outside storage. +// TypeError: (121-142): Type is required to live outside storage. diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_array_return_external.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_array_return_external.sol new file mode 100644 index 00000000..dbe030fb --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/mapping_array_return_external.sol @@ -0,0 +1,6 @@ +contract C { + function f() external pure returns (mapping(uint=>uint)[] storage m) { + } +} +// ---- +// TypeError: (53-84): Location has to be memory for publicly visible functions (remove the "storage" or "calldata" keyword). diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_array_return_internal.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_array_return_internal.sol new file mode 100644 index 00000000..8837c745 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/mapping_array_return_internal.sol @@ -0,0 +1,16 @@ +contract C { + mapping(uint=>uint)[] m; + function f() internal view returns (mapping(uint=>uint)[] storage) { + return m; + } + function g() private view returns (mapping(uint=>uint)[] storage) { + return m; + } + function h() internal view returns (mapping(uint=>uint)[] storage r) { + r = m; + } + function i() private view returns (mapping(uint=>uint)[] storage r) { + (r,r) = (m,m); + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_array_return_public.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_array_return_public.sol new file mode 100644 index 00000000..7dfecf19 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/mapping_array_return_public.sol @@ -0,0 +1,6 @@ +contract C { + function f() public pure returns (mapping(uint=>uint)[] storage m) { + } +} +// ---- +// TypeError: (51-82): Location has to be memory for publicly visible functions (remove the "storage" or "calldata" keyword). diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_return_internal.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_return_internal.sol index a46003f8..4912836e 100644 --- a/test/libsolidity/syntaxTests/types/mapping/mapping_return_internal.sol +++ b/test/libsolidity/syntaxTests/types/mapping/mapping_return_internal.sol @@ -1,4 +1,3 @@ -// This should be allowed in a future release. contract C { mapping(uint=>uint) m; function f() internal view returns (mapping(uint=>uint) storage) { @@ -15,7 +14,3 @@ contract C { } } // ---- -// TypeError: (127-146): Type is required to live outside storage. -// TypeError: (221-240): Type is required to live outside storage. -// TypeError: (316-345): Type is required to live outside storage. -// TypeError: (409-438): Type is required to live outside storage. diff --git a/test/libsolidity/syntaxTests/types/too_small_negative_numbers.sol b/test/libsolidity/syntaxTests/types/too_small_negative_numbers.sol new file mode 100644 index 00000000..66bd9a8e --- /dev/null +++ b/test/libsolidity/syntaxTests/types/too_small_negative_numbers.sol @@ -0,0 +1,4 @@ +contract C { + fixed8x80 a = -1e-100; +} +// ---- diff --git a/test/libsolidity/syntaxTests/types/zero_literal_to_bytesXX_explicit.sol b/test/libsolidity/syntaxTests/types/zero_literal_to_bytesXX_explicit.sol new file mode 100644 index 00000000..5d606089 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/zero_literal_to_bytesXX_explicit.sol @@ -0,0 +1,30 @@ +contract C { + function f() public pure { + bytes1 b1 = bytes1(0); + bytes2 b2 = bytes2(0); + bytes3 b3 = bytes3(0); + bytes4 b4 = bytes4(0); + bytes8 b8 = bytes8(0); + bytes16 b16 = bytes16(0); + bytes32 b32 = bytes32(0); + b1; b2; b3; b4; b8; b16; b32; + } + function g() public pure { + bytes1 b1 = bytes1(0x000); + bytes2 b2 = bytes2(0x00000); + bytes3 b3 = bytes3(0x0000000); + bytes4 b4 = bytes4(0x000000000); + bytes8 b8 = bytes8(0x00000000000000000); + b1; b2; b3; b4; b8; + } + function h() public pure { + bytes1 b1 = bytes1(0x0); + bytes2 b2 = bytes2(0x0); + bytes3 b3 = bytes3(0x0); + bytes4 b4 = bytes4(0x0); + bytes8 b8 = bytes8(0x0); + bytes16 b16 = bytes16(0x0); + bytes32 b32 = bytes32(0x0); + b1; b2; b3; b4; b8; b16; b32; + } +} diff --git a/test/libsolidity/syntaxTests/types/zero_literal_to_bytesXX_implicit.sol b/test/libsolidity/syntaxTests/types/zero_literal_to_bytesXX_implicit.sol new file mode 100644 index 00000000..48be0655 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/zero_literal_to_bytesXX_implicit.sol @@ -0,0 +1,30 @@ +contract C { + function f() public pure { + bytes1 b1 = 0; + bytes2 b2 = 0; + bytes3 b3 = 0; + bytes4 b4 = 0; + bytes8 b8 = 0; + bytes16 b16 = 0; + bytes32 b32 = 0; + b1; b2; b3; b4; b8; b16; b32; + } + function g() public pure { + bytes1 b1 = 0x000; + bytes2 b2 = 0x00000; + bytes3 b3 = 0x0000000; + bytes4 b4 = 0x000000000; + bytes8 b8 = 0x00000000000000000; + b1; b2; b3; b4; b8; + } + function h() public pure { + bytes1 b1 = 0x0; + bytes2 b2 = 0x0; + bytes3 b3 = 0x0; + bytes4 b4 = 0x0; + bytes8 b8 = 0x0; + bytes16 b16 = 0x0; + bytes32 b32 = 0x0; + b1; b2; b3; b4; b8; b16; b32; + } +} diff --git a/test/libsolidity/syntaxTests/viewPureChecker/builtin_functions.sol b/test/libsolidity/syntaxTests/viewPureChecker/builtin_functions.sol index 51e36a58..2cb185c9 100644 --- a/test/libsolidity/syntaxTests/viewPureChecker/builtin_functions.sol +++ b/test/libsolidity/syntaxTests/viewPureChecker/builtin_functions.sol @@ -9,7 +9,7 @@ contract C { function g() pure public { bytes32 x = keccak256("abc"); bytes32 y = sha256("abc"); - address z = ecrecover(bytes32(1), uint8(2), bytes32(3), bytes32(4)); + address z = ecrecover(bytes32(uint256(1)), uint8(2), bytes32(uint256(3)), bytes32(uint256(4))); require(true); assert(true); x; y; z; diff --git a/test/libsolidity/syntaxTests/viewPureChecker/builtin_functions_restrict_warning.sol b/test/libsolidity/syntaxTests/viewPureChecker/builtin_functions_restrict_warning.sol index 0b834022..4a651d21 100644 --- a/test/libsolidity/syntaxTests/viewPureChecker/builtin_functions_restrict_warning.sol +++ b/test/libsolidity/syntaxTests/viewPureChecker/builtin_functions_restrict_warning.sol @@ -2,7 +2,7 @@ contract C { function f() view public { bytes32 x = keccak256("abc"); bytes32 y = sha256("abc"); - address z = ecrecover(bytes32(1), uint8(2), bytes32(3), bytes32(4)); + address z = ecrecover(bytes32(uint256(1)), uint8(2), bytes32(uint256(3)), bytes32(uint256(4))); require(true); assert(true); x; y; z; @@ -10,12 +10,12 @@ contract C { function g() public { bytes32 x = keccak256("abc"); bytes32 y = sha256("abc"); - address z = ecrecover(bytes32(1), uint8(2), bytes32(3), bytes32(4)); + address z = ecrecover(bytes32(uint256(1)), uint8(2), bytes32(uint256(3)), bytes32(uint256(4))); require(true); assert(true); x; y; z; } } // ---- -// Warning: (17-261): Function state mutability can be restricted to pure -// Warning: (266-505): Function state mutability can be restricted to pure +// Warning: (17-288): Function state mutability can be restricted to pure +// Warning: (293-559): Function state mutability can be restricted to pure |