diff --git a/libsmtutil/SMTPortfolio.h b/libsmtutil/SMTPortfolio.h index aca50eef7..aab92f996 100644 --- a/libsmtutil/SMTPortfolio.h +++ b/libsmtutil/SMTPortfolio.h @@ -58,7 +58,7 @@ public: std::pair> check(std::vector const& _expressionsToEvaluate) override; std::vector unhandledQueries() override; - unsigned solvers() override { return m_solvers.size(); } + size_t solvers() override { return m_solvers.size(); } private: static bool solverAnswered(CheckResult result); diff --git a/libsmtutil/SolverInterface.h b/libsmtutil/SolverInterface.h index a3a3fb497..8dd73b035 100644 --- a/libsmtutil/SolverInterface.h +++ b/libsmtutil/SolverInterface.h @@ -402,7 +402,7 @@ public: virtual std::vector unhandledQueries() { return {}; } /// @returns how many SMT solvers this interface has. - virtual unsigned solvers() { return 1; } + virtual size_t solvers() { return 1; } protected: std::optional m_queryTimeout; diff --git a/libsmtutil/Z3Interface.cpp b/libsmtutil/Z3Interface.cpp index 3e01dd62c..46e601fdf 100644 --- a/libsmtutil/Z3Interface.cpp +++ b/libsmtutil/Z3Interface.cpp @@ -217,7 +217,7 @@ z3::expr Z3Interface::toZ3Expr(Expression const& _expr) else if (n == "int2bv") { size_t size = std::stoul(_expr.arguments[1].name); - return z3::int2bv(size, arguments[0]); + return z3::int2bv(static_cast(size), arguments[0]); } else if (n == "bv2int") { @@ -240,7 +240,7 @@ z3::expr Z3Interface::toZ3Expr(Expression const& _expr) else if (n == "tuple_get") { size_t index = stoul(_expr.arguments[1].name); - return z3::func_decl(m_context, Z3_get_tuple_sort_field_decl(m_context, z3Sort(*_expr.arguments[0].sort), index))(arguments[0]); + return z3::func_decl(m_context, Z3_get_tuple_sort_field_decl(m_context, z3Sort(*_expr.arguments[0].sort), static_cast(index)))(arguments[0]); } else if (n == "tuple_constructor") { @@ -367,7 +367,7 @@ z3::sort Z3Interface::z3Sort(Sort const& _sort) z3::func_decl_vector projs(m_context); z3::func_decl tupleConstructor = m_context.tuple_sort( tupleSort.name.c_str(), - tupleSort.members.size(), + static_cast(tupleSort.members.size()), cMembers.data(), sorts.data(), projs diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 5b7c36ca2..bd38b39ef 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -208,7 +208,9 @@ void IRGeneratorForStatements::initializeLocalVar(VariableDeclaration const& _va solAssert(m_context.isLocalVariable(_varDecl), "Must be a local variable."); auto const* type = _varDecl.type(); - if (auto const* refType = dynamic_cast(type)) + if (dynamic_cast(type)) + return; + else if (auto const* refType = dynamic_cast(type)) if (refType->dataStoredIn(DataLocation::Storage) && refType->isPointer()) return; @@ -1356,10 +1358,13 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) datacopy(, dataoffset(""), datasize("")) := () - let := create2(, , sub(, ), ) + let
:= create2(, , sub(, ), ) - let := create(, , sub(, )) + let
:= create(, , sub(, )) + + let := iszero(iszero(
)) + () )"); t("memPos", m_context.newYulVariable()); @@ -1376,7 +1381,11 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) t("saltSet", functionType->saltSet()); if (functionType->saltSet()) t("salt", IRVariable(_functionCall.expression()).part("salt").name()); - t("retVars", IRVariable(_functionCall).commaSeparatedList()); + solAssert(IRVariable(_functionCall).stackSlots().size() == 1, ""); + t("address", IRVariable(_functionCall).commaSeparatedList()); + t("isTryCall", _functionCall.annotation().tryCall); + if (_functionCall.annotation().tryCall) + t("success", IRNames::trySuccessConditionVariable(_functionCall)); m_code << t.render(); break; @@ -1993,28 +2002,27 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess) } case DataLocation::CallData: { - IRVariable var(m_context.newYulVariable(), *arrayType.baseType()); - define(var) << - m_utils.calldataArrayIndexAccessFunction(arrayType) << - "(" << - IRVariable(_indexAccess.baseExpression()).commaSeparatedList() << - ", " << - expressionAsType(*_indexAccess.indexExpression(), *TypeProvider::uint256()) << + string const indexAccessFunctionCall = + m_utils.calldataArrayIndexAccessFunction(arrayType) + + "(" + + IRVariable(_indexAccess.baseExpression()).commaSeparatedList() + + ", " + + expressionAsType(*_indexAccess.indexExpression(), *TypeProvider::uint256()) + ")\n"; if (arrayType.isByteArray()) define(_indexAccess) << m_utils.cleanupFunction(*arrayType.baseType()) << "(calldataload(" << - var.name() << + indexAccessFunctionCall << "))\n"; else if (arrayType.baseType()->isValueType()) define(_indexAccess) << m_utils.readFromCalldata(*arrayType.baseType()) << "(" << - var.commaSeparatedList() << + indexAccessFunctionCall << ")\n"; else - define(_indexAccess, var); + define(_indexAccess) << indexAccessFunctionCall; break; } } diff --git a/libsolidity/formal/EncodingContext.h b/libsolidity/formal/EncodingContext.h index 204c0e178..7c001f452 100644 --- a/libsolidity/formal/EncodingContext.h +++ b/libsolidity/formal/EncodingContext.h @@ -142,7 +142,7 @@ public: void pushSolver(); void popSolver(); void addAssertion(smtutil::Expression const& _e); - unsigned solverStackHeigh() { return m_assertions.size(); } const + size_t solverStackHeigh() { return m_assertions.size(); } const smtutil::SolverInterface* solver() { solAssert(m_solver, ""); diff --git a/libsolidity/formal/Predicate.cpp b/libsolidity/formal/Predicate.cpp index 8d1eba1b4..fb2ef9e8e 100644 --- a/libsolidity/formal/Predicate.cpp +++ b/libsolidity/formal/Predicate.cpp @@ -349,7 +349,7 @@ bool Predicate::fillArray(smtutil::Expression const& _expr, vector& _arr return false; // Sometimes the solver assigns huge lengths that are not related, // we should catch and ignore those. - unsigned index; + unsigned long index; try { index = stoul(*indexStr); diff --git a/libsolidity/formal/SymbolicState.cpp b/libsolidity/formal/SymbolicState.cpp index 16bc6e7bf..5d38eac0f 100644 --- a/libsolidity/formal/SymbolicState.cpp +++ b/libsolidity/formal/SymbolicState.cpp @@ -41,7 +41,7 @@ BlockchainVariable::BlockchainVariable( { members.emplace_back(component); sorts.emplace_back(sort); - m_componentIndices[component] = members.size() - 1; + m_componentIndices[component] = static_cast(members.size() - 1); } m_tuple = make_unique( make_shared(m_name + "_type", members, sorts), diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh index d0b6ef531..aa70e6d47 100755 --- a/test/cmdlineTests.sh +++ b/test/cmdlineTests.sh @@ -256,11 +256,11 @@ printTask "Running general commandline tests..." do printTask " - ${tdir}" - # Strip trailing slash from $tdir. `find` on MacOS X won't strip it and will produce double slashes. + # Strip trailing slash from $tdir. tdir=$(basename "${tdir}") - inputFiles="$(find "${tdir}" -name 'input.*' -type f -exec printf "%s\n" "{}" \;)" - inputCount="$(echo "${inputFiles}" | wc -l)" + inputFiles="$(ls -1 ${tdir}/input.* 2> /dev/null || true)" + inputCount="$(echo ${inputFiles} | wc -w)" if (( ${inputCount} > 1 )) then printError "Ambiguous input. Found input files in multiple formats:" diff --git a/test/libsolidity/ABIDecoderTests.cpp b/test/libsolidity/ABIDecoderTests.cpp index 524cb7119..d7c164a46 100644 --- a/test/libsolidity/ABIDecoderTests.cpp +++ b/test/libsolidity/ABIDecoderTests.cpp @@ -73,117 +73,6 @@ BOOST_AUTO_TEST_CASE(value_types) ) } -BOOST_AUTO_TEST_CASE(cleanup) -{ - string sourceCode = R"( - contract C { - function f(uint16 a, int16 b, address c, bytes3 d, bool e) - public pure returns (uint v, uint w, uint x, uint y, uint z) { - assembly { v := a w := b x := c y := d z := e} - } - } - )"; - bool newDecoder = solidity::test::CommonOptions::get().useABIEncoderV2; - BOTH_ENCODERS( - compileAndRun(sourceCode); - ABI_CHECK( - callContractFunction("f(uint16,int16,address,bytes3,bool)", 1, 2, 3, "a", true), - encodeArgs(u256(1), u256(2), u256(3), string("a"), true) - ); - ABI_CHECK( - callContractFunction( - "f(uint16,int16,address,bytes3,bool)", - u256(0xffffff), u256(0x1ffff), u256(-1), string("abcd"), u256(1) - ), - newDecoder ? bytes{} : encodeArgs(u256(0xffff), u256(-1), (u256(1) << 160) - 1, string("abc"), true) - ); - ABI_CHECK( - callContractFunction( - "f(uint16,int16,address,bytes3,bool)", - u256(0xffffff), u256(0), u256(0), string("bcd"), u256(1) - ), - newDecoder ? bytes{} : encodeArgs(u256(0xffff), u256(0), 0, string("bcd"), true) - ); - ABI_CHECK( - callContractFunction( - "f(uint16,int16,address,bytes3,bool)", - u256(0), u256(0x1ffff), u256(0), string("ab"), u256(1) - ), - newDecoder ? bytes{} : encodeArgs(u256(0), u256(-1), 0, string("ab"), true) - ); - ABI_CHECK( - callContractFunction( - "f(uint16,int16,address,bytes3,bool)", - u256(0), u256(0), u256(-1), string("ad"), u256(1) - ), - newDecoder ? bytes{} : encodeArgs(u256(0), u256(0), (u256(1) << 160) - 1, string("ad"), true) - ); - ABI_CHECK( - callContractFunction( - "f(uint16,int16,address,bytes3,bool)", - u256(0), u256(0), u256(0), string("abcd"), u256(1) - ), - newDecoder ? bytes{} : encodeArgs(u256(0), u256(0), 0, string("abc"), true) - ); - ABI_CHECK( - callContractFunction( - "f(uint16,int16,address,bytes3,bool)", - u256(0), u256(0), u256(0), string("abc"), u256(2) - ), - newDecoder ? bytes{} : encodeArgs(u256(0), u256(0), 0, string("abc"), true) - ); - newDecoder = true; - ) -} - -BOOST_AUTO_TEST_CASE(fixed_arrays) -{ - string sourceCode = R"( - contract C { - function f(uint16[3] memory a, uint16[2][3] memory b, uint i, uint j, uint k) - public pure returns (uint, uint) { - return (a[i], b[j][k]); - } - } - )"; - BOTH_ENCODERS( - compileAndRun(sourceCode); - bytes args = encodeArgs( - 1, 2, 3, - 11, 12, - 21, 22, - 31, 32, - 1, 2, 1 - ); - ABI_CHECK( - callContractFunction("f(uint16[3],uint16[2][3],uint256,uint256,uint256)", args), - encodeArgs(u256(2), u256(32)) - ); - ) -} - -BOOST_AUTO_TEST_CASE(calldata_arrays_too_large) -{ - string sourceCode = R"( - contract C { - function f(uint a, uint[] calldata b, uint c) external pure returns (uint) { - return 7; - } - } - )"; - BOTH_ENCODERS( - compileAndRun(sourceCode); - bytes args = encodeArgs( - 6, 0x60, 9, - (u256(1) << 255) + 2, 1, 2 - ); - ABI_CHECK( - callContractFunction("f(uint256,uint256[],uint256)", args), - encodeArgs() - ); - ) -} - BOOST_AUTO_TEST_CASE(decode_from_memory_simple) { string sourceCode = R"( @@ -463,121 +352,6 @@ BOOST_AUTO_TEST_CASE(validation_function_type) ) } -BOOST_AUTO_TEST_CASE(validation_function_type_inside_struct) -{ - string sourceCode = R"( - contract C { - struct S { function () external x; } - function f(S memory) public pure returns (uint r) { r = 1; } - function g(S calldata) external pure returns (uint r) { r = 2; } - function h(S calldata s) external pure returns (uint r) { s.x; r = 3; } - } - )"; - string validFun{"01234567890123456789abcd"}; - string invalidFun{"01234567890123456789abcdX"}; - NEW_ENCODER( - compileAndRun(sourceCode); - ABI_CHECK(callContractFunction("f((function))", validFun), encodeArgs(1)); - // Error because we copy to memory - ABI_CHECK(callContractFunction("f((function))", invalidFun), encodeArgs()); - ABI_CHECK(callContractFunction("g((function))", validFun), encodeArgs(2)); - // No error because x is not accessed. - ABI_CHECK(callContractFunction("g((function))", invalidFun), encodeArgs(2)); - ABI_CHECK(callContractFunction("h((function))", validFun), encodeArgs(3)); - // Error on access. - ABI_CHECK(callContractFunction("h((function))", invalidFun), encodeArgs()); - ) -} - -BOOST_AUTO_TEST_CASE(storage_ptr) -{ - string sourceCode = R"( - library L { - struct S { uint x; uint y; } - function f(uint[] storage r, S storage s) public returns (uint, uint, uint, uint) { - r[2] = 8; - s.x = 7; - return (r[0], r[1], s.x, s.y); - } - } - contract C { - uint8 x = 3; - L.S s; - uint[] r; - function f() public returns (uint, uint, uint, uint, uint, uint) { - r = new uint[](6); - r[0] = 1; - r[1] = 2; - r[2] = 3; - s.x = 11; - s.y = 12; - (uint a, uint b, uint c, uint d) = L.f(r, s); - return (r[2], s.x, a, b, c, d); - } - } - )"; - BOTH_ENCODERS( - compileAndRun(sourceCode, 0, "L"); - compileAndRun(sourceCode, 0, "C", bytes(), map{{"L", m_contractAddress}}); - ABI_CHECK(callContractFunction("f()"), encodeArgs(8, 7, 1, 2, 7, 12)); - ) -} - -BOOST_AUTO_TEST_CASE(struct_simple) -{ - string sourceCode = R"( - contract C { - struct S { uint a; uint8 b; uint8 c; bytes2 d; } - function f(S memory s) public pure returns (uint a, uint b, uint c, uint d) { - a = s.a; - b = s.b; - c = s.c; - d = uint16(s.d); - } - } - )"; - NEW_ENCODER( - compileAndRun(sourceCode, 0, "C"); - ABI_CHECK(callContractFunction("f((uint256,uint8,uint8,bytes2))", 1, 2, 3, "ab"), encodeArgs(1, 2, 3, 'a' * 0x100 + 'b')); - ) -} - -BOOST_AUTO_TEST_CASE(struct_validation) -{ - string sourceCode = R"( - contract C { - struct S { int16 a; uint8 b; bytes2 c; } - function f(S memory s) public pure returns (uint a, uint b, uint c) { - assembly { - a := mload(s) - b := mload(add(s, 0x20)) - c := mload(add(s, 0x40)) - } - } - } - )"; - u256 largeNeg("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01"); - NEW_ENCODER( - compileAndRun(sourceCode, 0, "C"); - ABI_CHECK( - callContractFunction("f((int16,uint8,bytes2))", largeNeg, 0xff, "ab"), - encodeArgs(largeNeg, 0xff, "ab") - ); - ABI_CHECK( - callContractFunction("f((int16,uint8,bytes2))", 0xff010, 0xff, "ab"), - encodeArgs() - ); - ABI_CHECK( - callContractFunction("f((int16,uint8,bytes2))", largeNeg, 0xff0002, "ab"), - encodeArgs() - ); - ABI_CHECK( - callContractFunction("f((int16,uint8,bytes2))", largeNeg, 0xff, "abcd"), - encodeArgs() - ); - ) -} - BOOST_AUTO_TEST_CASE(struct_short) { string sourceCode = R"( @@ -605,73 +379,6 @@ BOOST_AUTO_TEST_CASE(struct_short) ) } -BOOST_AUTO_TEST_CASE(struct_function) -{ - string sourceCode = R"( - contract C { - struct S { function () external returns (uint) f; uint b; } - function f(S memory s) public returns (uint, uint) { - return (s.f(), s.b); - } - function test() public returns (uint, uint) { - return this.f(S(this.g, 3)); - } - function g() public returns (uint) { return 7; } - } - )"; - NEW_ENCODER( - compileAndRun(sourceCode, 0, "C"); - ABI_CHECK(callContractFunction("test()"), encodeArgs(7, 3)); - ) -} - -BOOST_AUTO_TEST_CASE(mediocre_struct) -{ - string sourceCode = R"( - contract C { - struct S { C c; } - function f(uint a, S[2] memory s1, uint b) public returns (uint r1, C r2, uint r3) { - r1 = a; - r2 = s1[0].c; - r3 = b; - } - } - )"; - NEW_ENCODER( - compileAndRun(sourceCode, 0, "C"); - string sig = "f(uint256,(address)[2],uint256)"; - ABI_CHECK(callContractFunction(sig, - 7, u256(u160(m_contractAddress)), 0, 8 - ), encodeArgs(7, u256(u160(m_contractAddress)), 8)); - ) -} - -BOOST_AUTO_TEST_CASE(mediocre2_struct) -{ - string sourceCode = R"( - contract C { - struct S { C c; uint[] x; } - function f(uint a, S[2] memory s1, uint b) public returns (uint r1, C r2, uint r3) { - r1 = a; - r2 = s1[0].c; - r3 = b; - } - } - )"; - NEW_ENCODER( - compileAndRun(sourceCode, 0, "C"); - string sig = "f(uint256,(address,uint256[])[2],uint256)"; - ABI_CHECK(callContractFunction(sig, - 7, 0x60, 8, - 0x40, 7 * 0x20, - u256(u160(m_contractAddress)), 0x40, - 2, 0x11, 0x12, - 0x99, 0x40, - 4, 0x31, 0x32, 0x34, 0x35 - ), encodeArgs(7, u256(u160(m_contractAddress)), 8)); - ) -} - BOOST_AUTO_TEST_CASE(complex_struct) { string sourceCode = R"( @@ -731,108 +438,6 @@ BOOST_AUTO_TEST_CASE(complex_struct) ) } -BOOST_AUTO_TEST_CASE(return_dynamic_types_cross_call_simple) -{ - if (m_evmVersion == langutil::EVMVersion::homestead()) - return; - - string sourceCode = R"( - contract C { - function dyn() public returns (bytes memory) { - return "1234567890123456789012345678901234567890"; - } - function f() public returns (bytes memory) { - return this.dyn(); - } - } - )"; - BOTH_ENCODERS( - compileAndRun(sourceCode, 0, "C"); - ABI_CHECK(callContractFunction("f()"), encodeArgs(0x20, 40, string("1234567890123456789012345678901234567890"))); - ) -} - -BOOST_AUTO_TEST_CASE(return_dynamic_types_cross_call_advanced) -{ - if (m_evmVersion == langutil::EVMVersion::homestead()) - return; - - string sourceCode = R"( - contract C { - function dyn() public returns (bytes memory a, uint b, bytes20[] memory c, uint d) { - a = "1234567890123456789012345678901234567890"; - b = type(uint).max; - c = new bytes20[](4); - c[0] = bytes20(uint160(1234)); - c[3] = bytes20(uint160(6789)); - d = 0x1234; - } - function f() public returns (bytes memory, uint, bytes20[] memory, uint) { - return this.dyn(); - } - } - )"; - BOTH_ENCODERS( - compileAndRun(sourceCode, 0, "C"); - ABI_CHECK(callContractFunction("f()"), encodeArgs( - 0x80, u256(-1), 0xe0, 0x1234, - 40, string("1234567890123456789012345678901234567890"), - 4, u256(1234) << (8 * (32 - 20)), 0, 0, u256(6789) << (8 * (32 - 20)) - )); - ) -} - -BOOST_AUTO_TEST_CASE(return_dynamic_types_cross_call_out_of_range) -{ - string sourceCode = R"( - contract C { - function dyn(uint x) public returns (bytes memory a) { - assembly { - mstore(0, 0x20) - mstore(0x20, 0x21) - return(0, x) - } - } - function f(uint x) public returns (bool) { - this.dyn(x); - return true; - } - } - )"; - BOTH_ENCODERS( - compileAndRun(sourceCode, 0, "C"); - if (m_evmVersion == langutil::EVMVersion::homestead()) - { - ABI_CHECK(callContractFunction("f(uint256)", 0x60), encodeArgs(true)); - ABI_CHECK(callContractFunction("f(uint256)", 0x7f), encodeArgs(true)); - } - else - { - ABI_CHECK(callContractFunction("f(uint256)", 0x60), encodeArgs()); - ABI_CHECK(callContractFunction("f(uint256)", 0x61), encodeArgs(true)); - } - ABI_CHECK(callContractFunction("f(uint256)", 0x80), encodeArgs(true)); - ) -} - -BOOST_AUTO_TEST_CASE(out_of_bounds_bool_value) -{ - string sourceCode = R"( - contract C { - function f(bool b) public pure returns (bool) { return b; } - } - )"; - bool newDecoder = solidity::test::CommonOptions::get().useABIEncoderV2; - BOTH_ENCODERS( - compileAndRun(sourceCode); - ABI_CHECK(callContractFunction("f(bool)", true), encodeArgs(true)); - ABI_CHECK(callContractFunction("f(bool)", false), encodeArgs(false)); - ABI_CHECK(callContractFunctionNoEncoding("f(bool)", bytes(32, 0)), encodeArgs(0)); - ABI_CHECK(callContractFunctionNoEncoding("f(bool)", bytes(32, 0xff)), newDecoder ? encodeArgs() : encodeArgs(1)); - newDecoder = true; - ) -} - BOOST_AUTO_TEST_SUITE_END() } // end namespaces diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_fixed_arrays.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_fixed_arrays.sol new file mode 100644 index 000000000..b421f7bd0 --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_fixed_arrays.sol @@ -0,0 +1,10 @@ +contract C { + function f(uint16[3] memory a, uint16[2][3] memory b, uint i, uint j, uint k) + public pure returns (uint, uint) { + return (a[i], b[j][k]); + } +} +// ==== +// compileViaYul: also +// ---- +// f(uint16[3],uint16[2][3],uint256,uint256,uint256): 1, 2, 3, 11, 12, 21, 22, 31, 32, 1, 2, 1 -> 2, 32 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/bool_out_of_bounds.sol b/test/libsolidity/semanticTests/abiEncoderV1/bool_out_of_bounds.sol new file mode 100644 index 000000000..575d8012c --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV1/bool_out_of_bounds.sol @@ -0,0 +1,10 @@ +contract C { + function f(bool b) public pure returns (bool) { return b; } +} +// ==== +// ABIEncoderV1Only: true +// ---- +// f(bool): true -> true +// f(bool): false -> false +// f(bool): 0x000000 -> false +// f(bool): 0xffffff -> true \ No newline at end of file diff --git a/test/libsolidity/semanticTests/abiEncoderV1/calldata_arrays_too_large.sol b/test/libsolidity/semanticTests/abiEncoderV1/calldata_arrays_too_large.sol new file mode 100644 index 000000000..7b1f09e10 --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV1/calldata_arrays_too_large.sol @@ -0,0 +1,9 @@ +contract C { + function f(uint a, uint[] calldata b, uint c) external pure returns (uint) { + return 7; + } +} +// ==== +// compileViaYul: also +// ---- +// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x8000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE \ No newline at end of file diff --git a/test/libsolidity/semanticTests/abiEncoderV1/cleanup/cleanup.sol b/test/libsolidity/semanticTests/abiEncoderV1/cleanup/cleanup.sol new file mode 100644 index 000000000..a97ad107d --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV1/cleanup/cleanup.sol @@ -0,0 +1,16 @@ +contract C { + function f(uint16 a, int16 b, address c, bytes3 d, bool e) + public pure returns (uint v, uint w, uint x, uint y, uint z) { + assembly { v := a w := b x := c y := d z := e} + } +} +// ==== +// ABIEncoderV1Only: true +// ---- +// f(uint16,int16,address,bytes3,bool): 1, 2, 3, "a", true -> 1, 2, 3, "a", true +// f(uint16,int16,address,bytes3,bool): 0xffffff, 0x1ffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "abcd", 1 -> 0xffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffff, "abc", true +// f(uint16,int16,address,bytes3,bool): 0xffffff, 0, 0, "bcd", 1 -> 0xffff, 0, 0, "bcd", true +// f(uint16,int16,address,bytes3,bool): 0, 0x1ffff, 0, "ab", 1 -> 0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0, "ab", true +// f(uint16,int16,address,bytes3,bool): 0, 0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "ad", 1 -> 0, 0, 0xffffffffffffffffffffffffffffffffffffffff, "ad", true +// f(uint16,int16,address,bytes3,bool): 0, 0, 0, "abcd", 1 -> 0, 0, 0, "abc", true +// f(uint16,int16,address,bytes3,bool): 0, 0, 0, "abc", 2 -> 0, 0, 0, "abc", true diff --git a/test/libsolidity/semanticTests/abiEncoderV1/return_dynamic_types_cross_call_advanced.sol b/test/libsolidity/semanticTests/abiEncoderV1/return_dynamic_types_cross_call_advanced.sol new file mode 100644 index 000000000..e72554356 --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV1/return_dynamic_types_cross_call_advanced.sol @@ -0,0 +1,18 @@ +contract C { + function dyn() public returns (bytes memory a, uint b, bytes20[] memory c, uint d) { + a = "1234567890123456789012345678901234567890"; + b = type(uint).max; + c = new bytes20[](4); + c[0] = bytes20(uint160(1234)); + c[3] = bytes20(uint160(6789)); + d = 0x1234; + } + function f() public returns (bytes memory, uint, bytes20[] memory, uint) { + return this.dyn(); + } +} +// ==== +// compileViaYul: also +// EVMVersion: >homestead +// ---- +// f() -> 0x80, -1, 0xe0, 0x1234, 40, "12345678901234567890123456789012", "34567890", 4, 97767552542602192590433234714624, 0, 0, 537879995309340587922569878831104 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/return_dynamic_types_cross_call_out_of_range_1.sol b/test/libsolidity/semanticTests/abiEncoderV1/return_dynamic_types_cross_call_out_of_range_1.sol new file mode 100644 index 000000000..c90180f49 --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV1/return_dynamic_types_cross_call_out_of_range_1.sol @@ -0,0 +1,20 @@ +contract C { + function dyn(uint x) public returns (bytes memory a) { + assembly { + mstore(0, 0x20) + mstore(0x20, 0x21) + return(0, x) + } + } + function f(uint x) public returns (bool) { + this.dyn(x); + return true; + } +} +// ==== +// compileViaYul: also +// EVMVersion: =homestead +// ---- +// f(uint256): 0x60 -> true +// f(uint256): 0x7f -> true +// f(uint256): 0x80 -> true \ No newline at end of file diff --git a/test/libsolidity/semanticTests/abiEncoderV1/return_dynamic_types_cross_call_out_of_range_2.sol b/test/libsolidity/semanticTests/abiEncoderV1/return_dynamic_types_cross_call_out_of_range_2.sol new file mode 100644 index 000000000..b5bca26d3 --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV1/return_dynamic_types_cross_call_out_of_range_2.sol @@ -0,0 +1,20 @@ +contract C { + function dyn(uint x) public returns (bytes memory a) { + assembly { + mstore(0, 0x20) + mstore(0x20, 0x21) + return(0, x) + } + } + function f(uint x) public returns (bool) { + this.dyn(x); + return true; + } +} +// ==== +// compileViaYul: also +// EVMVersion: >homestead +// ---- +// f(uint256): 0x60 -> FAILURE +// f(uint256): 0x61 -> true +// f(uint256): 0x80 -> true diff --git a/test/libsolidity/semanticTests/abiEncoderV1/return_dynamic_types_cross_call_simple.sol b/test/libsolidity/semanticTests/abiEncoderV1/return_dynamic_types_cross_call_simple.sol new file mode 100644 index 000000000..360eb7af0 --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV1/return_dynamic_types_cross_call_simple.sol @@ -0,0 +1,13 @@ +contract C { + function dyn() public returns (bytes memory) { + return "1234567890123456789012345678901234567890"; + } + function f() public returns (bytes memory) { + return this.dyn(); + } +} +// ==== +// compileViaYul: also +// EVMVersion: >homestead +// ---- +// f() -> 0x20, 40, "12345678901234567890123456789012", "34567890" diff --git a/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol new file mode 100644 index 000000000..eb67bf38d --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol @@ -0,0 +1,26 @@ +library L { + struct S { uint x; uint y; } + function f(uint[] storage r, S storage s) public returns (uint, uint, uint, uint) { + r[2] = 8; + s.x = 7; + return (r[0], r[1], s.x, s.y); + } +} +contract C { + uint8 x = 3; + L.S s; + uint[] r; + function f() public returns (uint, uint, uint, uint, uint, uint) { + r = new uint[](6); + r[0] = 1; + r[1] = 2; + r[2] = 3; + s.x = 11; + s.y = 12; + (uint a, uint b, uint c, uint d) = L.f(r, s); + return (r[2], s.x, a, b, c, d); + } +} +// ---- +// library: L +// f() -> 8, 7, 1, 2, 7, 12 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/bool_out_of_bounds.sol b/test/libsolidity/semanticTests/abiEncoderV2/bool_out_of_bounds.sol new file mode 100644 index 000000000..069e723b5 --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV2/bool_out_of_bounds.sol @@ -0,0 +1,12 @@ +pragma experimental ABIEncoderV2; + +contract C { + function f(bool b) public pure returns (bool) { return b; } +} +// ==== +// compileViaYul: also +// ---- +// f(bool): true -> true +// f(bool): false -> false +// f(bool): 0x000000 -> false +// f(bool): 0xffffff -> FAILURE diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array_function_types.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array_function_types.sol index c9ccc88a8..26045f60d 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array_function_types.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array_function_types.sol @@ -25,6 +25,8 @@ contract C { return reenc ? this.f_reenc(a) : this.f(a); } } +// ==== +// compileViaYul: also // ---- // g(bool): false -> 23, 37, 71 // g(bool): true -> 23, 37, 71 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/cleanup/cleanup.sol b/test/libsolidity/semanticTests/abiEncoderV2/cleanup/cleanup.sol new file mode 100644 index 000000000..08ec5ec87 --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV2/cleanup/cleanup.sol @@ -0,0 +1,18 @@ +pragma experimental ABIEncoderV2; + +contract C { + function f(uint16 a, int16 b, address c, bytes3 d, bool e) + public pure returns (uint v, uint w, uint x, uint y, uint z) { + assembly { v := a w := b x := c y := d z := e} + } +} +// ==== +// compileViaYul: also +// ---- +// f(uint16,int16,address,bytes3,bool): 1, 2, 3, "a", true -> 1, 2, 3, "a", true +// f(uint16,int16,address,bytes3,bool): 0xffffff, 0x1ffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "abcd", 1 -> FAILURE +// f(uint16,int16,address,bytes3,bool): 0xffffff, 0, 0, "bcd", 1 -> FAILURE +// f(uint16,int16,address,bytes3,bool): 0, 0x1ffff, 0, "ab", 1 -> FAILURE +// f(uint16,int16,address,bytes3,bool): 0, 0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "ad", 1 -> FAILURE +// f(uint16,int16,address,bytes3,bool): 0, 0, 0, "abcd", 1 -> FAILURE +// f(uint16,int16,address,bytes3,bool): 0, 0, 0, "abc", 2 -> FAILURE diff --git a/test/libsolidity/semanticTests/abiEncoderV2/struct/mediocre2_struct.sol b/test/libsolidity/semanticTests/abiEncoderV2/struct/mediocre2_struct.sol new file mode 100644 index 000000000..e4ffcb422 --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV2/struct/mediocre2_struct.sol @@ -0,0 +1,14 @@ +pragma experimental ABIEncoderV2; + +contract C { + struct S { C c; uint[] x; } + function f(uint a, S[2] memory s1, uint b) public returns (uint r1, C r2, uint r3) { + r1 = a; + r2 = s1[0].c; + r3 = b; + } +} +// ==== +// compileViaYul: also +// ---- +// f(uint256,(address,uint256[])[2],uint256): 7, 0x60, 8, 0x40, 0xE0, 0x0, 0x40, 2, 0x11, 0x12, 0x99, 0x40, 4, 0x31, 0x32, 0x34, 0x35 -> 7, 0x0, 8 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/struct/mediocre_struct.sol b/test/libsolidity/semanticTests/abiEncoderV2/struct/mediocre_struct.sol new file mode 100644 index 000000000..4f05afe9b --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV2/struct/mediocre_struct.sol @@ -0,0 +1,14 @@ +pragma experimental ABIEncoderV2; + +contract C { + struct S { C c; } + function f(uint a, S[2] memory s1, uint b) public returns (uint r1, C r2, uint r3) { + r1 = a; + r2 = s1[0].c; + r3 = b; + } +} +// ==== +// compileViaYul: also +// ---- +// f(uint256,(address)[2],uint256): 7, 0, 0, 8 -> 7, 0, 8 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/struct/struct_function.sol b/test/libsolidity/semanticTests/abiEncoderV2/struct/struct_function.sol new file mode 100644 index 000000000..4dcf6c010 --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV2/struct/struct_function.sol @@ -0,0 +1,16 @@ +pragma experimental ABIEncoderV2; + +contract C { + struct S { function () external returns (uint) f; uint b; } + function f(S memory s) public returns (uint, uint) { + return (s.f(), s.b); + } + function test() public returns (uint, uint) { + return this.f(S(this.g, 3)); + } + function g() public returns (uint) { return 7; } +} +// ==== +// compileViaYul: also +// ---- +// test() -> 7, 3 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/struct/struct_short.sol b/test/libsolidity/semanticTests/abiEncoderV2/struct/struct_short.sol new file mode 100644 index 000000000..a1eae4e8b --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV2/struct/struct_short.sol @@ -0,0 +1,13 @@ +pragma experimental ABIEncoderV2; + +contract C { + struct S { int a; uint b; bytes16 c; } + function f(S memory s) public pure returns (S memory q) { + q = s; + } +} +// ==== +// compileViaYul: also +// ---- +// f((int256,uint256,bytes16)): 0xff010, 0xff0002, "abcd" -> 0xff010, 0xff0002, "abcd" +// f((int256,uint256,bytes16)): 0xff010, 0xff0002, 0x1111222233334444555566667777888800000000000000000000000000000000 -> 0xff010, 0xff0002, left(0x11112222333344445555666677778888) diff --git a/test/libsolidity/semanticTests/abiEncoderV2/struct/struct_simple.sol b/test/libsolidity/semanticTests/abiEncoderV2/struct/struct_simple.sol new file mode 100644 index 000000000..ccef5ddc0 --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV2/struct/struct_simple.sol @@ -0,0 +1,15 @@ +pragma experimental ABIEncoderV2; + +contract C { + struct S { uint a; uint8 b; uint8 c; bytes2 d; } + function f(S memory s) public pure returns (uint a, uint b, uint c, uint d) { + a = s.a; + b = s.b; + c = s.c; + d = uint16(s.d); + } +} +// ==== +// compileViaYul: also +// ---- +// f((uint256,uint8,uint8,bytes2)): 1, 2, 3, "ab" -> 1, 2, 3, 0x6162 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/struct/struct_validation.sol b/test/libsolidity/semanticTests/abiEncoderV2/struct/struct_validation.sol new file mode 100644 index 000000000..f8c77be64 --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV2/struct/struct_validation.sol @@ -0,0 +1,19 @@ +pragma experimental ABIEncoderV2; + +contract C { + struct S { int16 a; uint8 b; bytes2 c; } + function f(S memory s) public pure returns (uint a, uint b, uint c) { + assembly { + a := mload(s) + b := mload(add(s, 0x20)) + c := mload(add(s, 0x40)) + } + } +} +// ==== +// compileViaYul: also +// ---- +// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, "ab" -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, "ab" +// f((int16,uint8,bytes2)): 0xff010, 0xff, "ab" -> FAILURE +// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff0002, "ab" -> FAILURE +// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, "abcd" -> FAILURE diff --git a/test/libsolidity/semanticTests/abiEncoderV2/struct/validation_function_type_inside_struct.sol b/test/libsolidity/semanticTests/abiEncoderV2/struct/validation_function_type_inside_struct.sol new file mode 100644 index 000000000..7944262a3 --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV2/struct/validation_function_type_inside_struct.sol @@ -0,0 +1,17 @@ +pragma experimental ABIEncoderV2; + +contract C { + struct S { function () external x; } + function f(S memory) public pure returns (uint r) { r = 1; } + function g(S calldata) external pure returns (uint r) { r = 2; } + function h(S calldata s) external pure returns (uint r) { s.x; r = 3; } +} +// ==== +// compileViaYul: also +// ---- +// f((function)): "01234567890123456789abcd" -> 1 +// f((function)): "01234567890123456789abcdX" -> FAILURE +// g((function)): "01234567890123456789abcd" -> 2 +// g((function)): "01234567890123456789abcdX" -> 2 +// h((function)): "01234567890123456789abcd" -> 3 +// h((function)): "01234567890123456789abcdX" -> FAILURE diff --git a/test/libsolidity/semanticTests/functionCall/mapping_internal_return.sol b/test/libsolidity/semanticTests/functionCall/mapping_internal_return.sol index 7756a92b1..b152298b9 100644 --- a/test/libsolidity/semanticTests/functionCall/mapping_internal_return.sol +++ b/test/libsolidity/semanticTests/functionCall/mapping_internal_return.sol @@ -17,6 +17,8 @@ contract test { return (a[0], a[1], a[2], b[0], b[1], b[2]); } } +// ==== +// compileViaYul: also // ---- // g() -> 0, 42, 0, 0, 84, 21 // h() -> 0, 42, 0, 0, 84, 17 diff --git a/test/libsolidity/semanticTests/immutable/getter_call_in_constructor.sol b/test/libsolidity/semanticTests/immutable/getter_call_in_constructor.sol index 2ef12c04a..fd2300d43 100644 --- a/test/libsolidity/semanticTests/immutable/getter_call_in_constructor.sol +++ b/test/libsolidity/semanticTests/immutable/getter_call_in_constructor.sol @@ -12,6 +12,7 @@ contract C { } } // ==== +// compileViaYul: also // EVMVersion: >=tangerineWhistle // ---- // f() -> true diff --git a/test/libsolidity/semanticTests/salted_create/salted_create.sol b/test/libsolidity/semanticTests/salted_create/salted_create.sol index b20adf74b..6a08fb18a 100644 --- a/test/libsolidity/semanticTests/salted_create/salted_create.sol +++ b/test/libsolidity/semanticTests/salted_create/salted_create.sol @@ -17,6 +17,7 @@ contract A { } } // ==== +// compileViaYul: also // EVMVersion: >=constantinople // ---- // different_salt() -> true diff --git a/test/libsolidity/semanticTests/tryCatch/create.sol b/test/libsolidity/semanticTests/tryCatch/create.sol index ad7f734c7..7fd776f6d 100644 --- a/test/libsolidity/semanticTests/tryCatch/create.sol +++ b/test/libsolidity/semanticTests/tryCatch/create.sol @@ -26,6 +26,7 @@ contract C { } } // ==== +// compileViaYul: also // EVMVersion: >=byzantium // ---- // f() -> 0, 0, 96, 13, "test message."