diff --git a/Changelog.md b/Changelog.md index 27e1cb33a29f..26f28d21d978 100644 --- a/Changelog.md +++ b/Changelog.md @@ -10,6 +10,7 @@ Compiler Features: Bugfixes: * Codegen: Fix internal compiler error when emitting events via module member access. * TypeChecker: Fix error and event selectors not being considered compile-time constant. +* TypeChecker: Fix `string.concat` and `bytes.concat` with constant arguments not being considered compile-time constant. ### 0.8.31 (2025-12-03) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index f5c093dbd411..ab8f00a3082b 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -3271,11 +3271,28 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) // TODO some members might be pure, but for example `address(0x123).balance` is not pure // although every subexpression is, so leaving this limited for now. if (auto tt = dynamic_cast(exprType)) + { if ( tt->actualType()->category() == Type::Category::Enum || tt->actualType()->category() == Type::Category::UserDefinedValueType ) annotation.isPure = true; + + // `concat` purity depends also on its arguments, but this is checked later, in visit(FunctionCall...) + // This covers `bytes.concat` and `string.concat`. + if (tt->actualType()->category() == Type::Category::Array) + { + if ( + auto const* funcType = dynamic_cast(annotation.type); + funcType && + ( + funcType->kind() == FunctionType::Kind::StringConcat || + funcType->kind() == FunctionType::Kind::BytesConcat + ) + ) + annotation.isPure = true; + } + } if ( auto const* functionType = dynamic_cast(exprType); functionType && @@ -3392,6 +3409,16 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) if (!annotation.isPure.set()) annotation.isPure = false; + if ( + auto const* funcType = dynamic_cast(annotation.type); + funcType && + funcType->kind() != FunctionType::Kind::Declaration && + funcType->kind() != FunctionType::Kind::Internal && + funcType->kind() != FunctionType::Kind::Error && + funcType->kind() != FunctionType::Kind::Event + ) + solAssert(funcType->isPure() == *annotation.isPure); + return false; } diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index f5c83b0cf991..316d99ba3edc 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -3713,7 +3713,9 @@ bool FunctionType::isPure() const m_kind == Kind::ABIDecode || m_kind == Kind::MetaType || m_kind == Kind::Wrap || - m_kind == Kind::Unwrap; + m_kind == Kind::Unwrap || + m_kind == Kind::BytesConcat || + m_kind == Kind::StringConcat; } TypePointers FunctionType::parseElementaryTypeVector(strings const& _types) diff --git a/test/libsolidity/semanticTests/constants/assign_type_info.sol b/test/libsolidity/semanticTests/constants/assign_type_info.sol new file mode 100644 index 000000000000..0fca83d547bc --- /dev/null +++ b/test/libsolidity/semanticTests/constants/assign_type_info.sol @@ -0,0 +1,13 @@ +contract A { +} + +contract B { + bytes constant creationCode = type(A).creationCode; + bytes constant runtimeCode = type(A).runtimeCode; + + function nonEmptyCode() public pure returns (bool) { + return creationCode.length > 0 && runtimeCode.length > 0; + } +} +// ---- +// nonEmptyCode() -> true diff --git a/test/libsolidity/syntaxTests/array/concat/bytes_concat_valid_type_literal.sol b/test/libsolidity/syntaxTests/array/concat/bytes_concat_valid_type_literal.sol index f39e9039638d..ff003ca8a025 100644 --- a/test/libsolidity/syntaxTests/array/concat/bytes_concat_valid_type_literal.sol +++ b/test/libsolidity/syntaxTests/array/concat/bytes_concat_valid_type_literal.sol @@ -1,6 +1,6 @@ contract C { - function f() public pure { - bytes.concat( + function f() public pure returns (bytes memory) { + return bytes.concat( hex"00", hex"aabbcc", unicode"abc", diff --git a/test/libsolidity/syntaxTests/array/concat/bytes_concat_wrong_type_empty_string_literal.sol b/test/libsolidity/syntaxTests/array/concat/bytes_concat_wrong_type_empty_string_literal.sol index afba249f8d4a..a58cf9f3dd92 100644 --- a/test/libsolidity/syntaxTests/array/concat/bytes_concat_wrong_type_empty_string_literal.sol +++ b/test/libsolidity/syntaxTests/array/concat/bytes_concat_wrong_type_empty_string_literal.sol @@ -1,6 +1,6 @@ contract C { - function f() public pure { - bytes.concat(hex"", unicode"", ""); + function f() public pure returns (bytes memory) { + return bytes.concat(hex"", unicode"", ""); } } // ---- diff --git a/test/libsolidity/syntaxTests/constants/initialization/abi_decode_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/abi_decode_const_args.sol new file mode 100644 index 000000000000..6f597ae73a6e --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/abi_decode_const_args.sol @@ -0,0 +1,7 @@ +bytes constant aEncoded = abi.encode( + hex"aaaa" +); + +contract A { + bytes constant a = abi.decode(aEncoded, (bytes)); +} diff --git a/test/libsolidity/syntaxTests/constants/initialization/abi_decode_non_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/abi_decode_non_const_args.sol new file mode 100644 index 000000000000..e5772333a005 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/abi_decode_non_const_args.sol @@ -0,0 +1,9 @@ +contract A { + function encoded() private view returns (bytes memory) { + return abi.encode(hex"aaaa"); + } + + bytes constant a = abi.decode(encoded(), (bytes)); +} +// ---- +// TypeError 8349: (142-172): Initial value for constant variable has to be compile-time constant. diff --git a/test/libsolidity/syntaxTests/constants/initialization/abi_encode_call_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/abi_encode_call_const_args.sol new file mode 100644 index 000000000000..e716694cc311 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/abi_encode_call_const_args.sol @@ -0,0 +1,5 @@ +contract A { + bool constant FLAG = true; + function f(uint, bool) external {} + bytes constant fCallA = abi.encodeCall(A.f, (123, FLAG)); +} diff --git a/test/libsolidity/syntaxTests/constants/initialization/abi_encode_call_non_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/abi_encode_call_non_const_args.sol new file mode 100644 index 000000000000..b49213742efe --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/abi_encode_call_non_const_args.sol @@ -0,0 +1,11 @@ +contract A { + function f(uint a) external {} + + function getA() private view returns(uint) { + return 1; + } + + bytes constant fCallA = abi.encodeCall(A.f, (getA())); +} +// ---- +// TypeError 8349: (151-180): Initial value for constant variable has to be compile-time constant. diff --git a/test/libsolidity/syntaxTests/constants/abi_encoding_constant.sol b/test/libsolidity/syntaxTests/constants/initialization/abi_encoding_builtin_const_args.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/abi_encoding_constant.sol rename to test/libsolidity/syntaxTests/constants/initialization/abi_encoding_builtin_const_args.sol diff --git a/test/libsolidity/syntaxTests/constants/initialization/abi_encoding_builtin_non_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/abi_encoding_builtin_non_const_args.sol new file mode 100644 index 000000000000..7e399a0d00d4 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/abi_encoding_builtin_non_const_args.sol @@ -0,0 +1,13 @@ +contract C { + uint k = 1; + + bytes32 constant a = keccak256(abi.encode(1, k)); + bytes32 constant b = keccak256(abi.encodePacked(uint(1), k)); + bytes32 constant c = keccak256(abi.encodeWithSelector(0x12345678, k, 2)); + bytes32 constant d = keccak256(abi.encodeWithSignature("f()", 1, k)); +} +// ---- +// TypeError 8349: (55-82): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (109-148): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (175-226): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (253-300): Initial value for constant variable has to be compile-time constant. diff --git a/test/libsolidity/syntaxTests/constants/addmod_zero.sol b/test/libsolidity/syntaxTests/constants/initialization/addmod_by_zero.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/addmod_zero.sol rename to test/libsolidity/syntaxTests/constants/initialization/addmod_by_zero.sol diff --git a/test/libsolidity/syntaxTests/constants/addmod_mulmod_rational.sol b/test/libsolidity/syntaxTests/constants/initialization/addmod_mulmod_rational_arg.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/addmod_mulmod_rational.sol rename to test/libsolidity/syntaxTests/constants/initialization/addmod_mulmod_rational_arg.sol diff --git a/test/libsolidity/syntaxTests/constants/initialization/block_tx_msg_property.sol b/test/libsolidity/syntaxTests/constants/initialization/block_tx_msg_property.sol new file mode 100644 index 000000000000..54381a2573a1 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/block_tx_msg_property.sol @@ -0,0 +1,80 @@ +bytes32 constant blockhGlobal = blockhash(1); +bytes32 constant blobhGlobal = blobhash(1); +uint constant bfGlobal = block.basefee; +uint constant blobbfGlobal = block.blobbasefee; +uint constant chainIdGlobal = block.chainid; +address constant coinbaseGlobal = block.coinbase; +uint constant diffGlobal = block.difficulty; +uint constant gaslimitGlobal = block.gaslimit; +uint constant numberGlobal = block.number; +uint constant prevrandaoGlobal = block.prevrandao; +uint constant timestampGlobal = block.timestamp; +uint constant gGlobal = gasleft(); +bytes constant dataGlobal = msg.data; +address constant senderGlobal = msg.sender; +bytes4 constant sigGlobal = msg.sig; +uint constant valueGlobal = msg.value; +uint constant gaspriceGlobal = tx.gasprice; +address constant originGlobal = tx.origin; + +contract A { + bytes32 constant blockh = blockhash(1); + bytes32 constant blobh = blobhash(1); + uint constant bf = block.basefee; + uint constant blobbf = block.blobbasefee; + uint constant chainId = block.chainid; + address constant coinbase = block.coinbase; + uint constant diff = block.difficulty; + uint constant gaslimit = block.gaslimit; + uint constant number = block.number; + uint constant prevrandao = block.prevrandao; + uint constant timestamp = block.timestamp; + uint constant g = gasleft(); + bytes constant data = msg.data; + address constant sender = msg.sender; + bytes4 constant sig = msg.sig; + uint constant value = msg.value; + uint constant gasprice = tx.gasprice; + address constant origin = tx.origin; +} +// ==== +// EVMVersion: >=cancun +// ---- +// TypeError 8349: (32-44): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (77-88): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (115-128): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (159-176): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (208-221): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (257-271): Initial value for constant variable has to be compile-time constant. +// Warning 8417: (300-316): Since the VM version paris, "difficulty" was replaced by "prevrandao", which now returns a random number based on the beacon chain. +// TypeError 8349: (300-316): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (349-363): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (394-406): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (441-457): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (491-506): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (532-541): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (571-579): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (613-623): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (653-660): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (690-699): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (732-743): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (777-786): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (832-844): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (875-886): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (911-924): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (953-970): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1000-1013): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1047-1061): Initial value for constant variable has to be compile-time constant. +// Warning 8417: (1088-1104): Since the VM version paris, "difficulty" was replaced by "prevrandao", which now returns a random number based on the beacon chain. +// TypeError 8349: (1088-1104): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1135-1149): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1178-1190): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1223-1239): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1271-1286): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1310-1319): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1347-1355): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1387-1397): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1425-1432): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1460-1469): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1500-1511): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (1543-1552): Initial value for constant variable has to be compile-time constant. diff --git a/test/libsolidity/syntaxTests/constants/initialization/bytes_concat_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/bytes_concat_const_args.sol new file mode 100644 index 000000000000..2d87ba56c48f --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/bytes_concat_const_args.sol @@ -0,0 +1,11 @@ +bytes constant aaaa = hex"aaaa"; + +bytes constant abcGlobal = bytes.concat(aaaa, hex"bbbb", hex"cccc"); + +contract A { + bytes public constant abc = bytes.concat(aaaa, hex"bbbb", hex"cccc"); + + bytes public constant abcCopy = abc; + bytes public constant abcGlobalCopy = abcGlobal; + bytes public constant abcabc = bytes.concat(abc, abcGlobal); +} diff --git a/test/libsolidity/syntaxTests/constants/initialization/bytes_concat_non_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/bytes_concat_non_const_args.sol new file mode 100644 index 000000000000..225731c1ffde --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/bytes_concat_non_const_args.sol @@ -0,0 +1,17 @@ +contract A { + function getData() public view returns (bytes memory) { + return msg.data; + } + + function getDataPure() public pure returns (bytes memory) { + return hex"ffff"; + } + + bytes constant abData = bytes.concat(hex"aaaa", hex"bbbb", msg.data); + bytes constant abgetData = bytes.concat(hex"aaaa", hex"bbbb", getData()); + bytes constant abgetDataPure = bytes.concat(hex"aaaa", hex"bbbb", getDataPure()); +} +// ---- +// TypeError 8349: (230-274): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (307-352): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (389-438): Initial value for constant variable has to be compile-time constant. diff --git a/test/libsolidity/syntaxTests/constants/cyclic_dependency_1.sol b/test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_1.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/cyclic_dependency_1.sol rename to test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_1.sol diff --git a/test/libsolidity/syntaxTests/constants/cyclic_dependency_2.sol b/test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_2.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/cyclic_dependency_2.sol rename to test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_2.sol diff --git a/test/libsolidity/syntaxTests/constants/cyclic_dependency_3.sol b/test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_3.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/cyclic_dependency_3.sol rename to test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_3.sol diff --git a/test/libsolidity/syntaxTests/constants/cyclic_dependency_4.sol b/test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_4.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/cyclic_dependency_4.sol rename to test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_4.sol diff --git a/test/libsolidity/syntaxTests/constants/cyclic_dependency_5.sol b/test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_5.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/cyclic_dependency_5.sol rename to test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_5.sol diff --git a/test/libsolidity/syntaxTests/constants/cyclic_dependency_file_constants.sol b/test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_file.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/cyclic_dependency_file_constants.sol rename to test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_file.sol diff --git a/test/libsolidity/syntaxTests/constants/cyclic_dependency_file_and_library_constants.sol b/test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_file_and_library.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/cyclic_dependency_file_and_library_constants.sol rename to test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_file_and_library.sol diff --git a/test/libsolidity/syntaxTests/constants/cyclic_dependency_library_constants.sol b/test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_library.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/cyclic_dependency_library_constants.sol rename to test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_library.sol diff --git a/test/libsolidity/syntaxTests/constants/division_by_zero.sol b/test/libsolidity/syntaxTests/constants/initialization/division_by_zero.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/division_by_zero.sol rename to test/libsolidity/syntaxTests/constants/initialization/division_by_zero.sol diff --git a/test/libsolidity/syntaxTests/constants/assign_constant_function_value.sol b/test/libsolidity/syntaxTests/constants/initialization/function_pointer_call.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/assign_constant_function_value.sol rename to test/libsolidity/syntaxTests/constants/initialization/function_pointer_call.sol diff --git a/test/libsolidity/syntaxTests/constants/initialization/math_builtin_opcode_based_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/math_builtin_opcode_based_const_args.sol new file mode 100644 index 000000000000..aa13e02b4d1e --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/math_builtin_opcode_based_const_args.sol @@ -0,0 +1,14 @@ +uint256 constant k = 7; +bytes constant data = hex"ffff"; + +uint256 constant amodGlobal = addmod(1, 8, k); +uint256 constant mmodGlobal = mulmod(1, 8, k); +bytes32 constant keccakGlobal = keccak256(hex"ffff"); +bytes32 constant keccakConstArgGlobal = keccak256(data); + +contract A { + uint256 constant amod = addmod(1, 8, k); + uint256 constant mmod = mulmod(1, 8, k); + bytes32 constant keccak = keccak256(hex"ffff"); + bytes32 constant keccakConstArg = keccak256(data); +} diff --git a/test/libsolidity/syntaxTests/constants/initialization/math_builtin_opcode_based_non_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/math_builtin_opcode_based_non_const_args.sol new file mode 100644 index 000000000000..208437ab7045 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/math_builtin_opcode_based_non_const_args.sol @@ -0,0 +1,12 @@ +contract A { + uint256 k = 7; + uint256 constant amod = addmod(1, 8, k); + uint256 constant mmod = mulmod(1, 8, k); + + bytes data = hex"ffff"; + bytes32 constant keccak = keccak256(data); +} +// ---- +// TypeError 8349: (60-75): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (105-120): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (181-196): Initial value for constant variable has to be compile-time constant. diff --git a/test/libsolidity/syntaxTests/constants/initialization/math_builtin_precompile_based_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/math_builtin_precompile_based_const_args.sol new file mode 100644 index 000000000000..57626ec2f362 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/math_builtin_precompile_based_const_args.sol @@ -0,0 +1,16 @@ +uint8 constant k = 1; +bytes constant data = hex"ffff"; + +bytes32 constant sGlobal = sha256(hex"ffff"); +bytes32 constant sConstArgGlobal = sha256(data); +address constant addrGlobal = ecrecover("1234", k, "0", abi.decode("", (bytes2))); +bytes20 constant ripemdGlobal = ripemd160(hex"ffff"); +bytes20 constant ripemdConstArgGlobal = ripemd160(data); + +contract A { + bytes32 constant s = sha256(hex"ffff"); + bytes32 constant sConstArg = sha256(data); + address constant addr = ecrecover("1234", k, "0", abi.decode("", (bytes2))); + bytes20 constant ripemd = ripemd160(hex"ffff"); + bytes20 constant ripemdConstArg = ripemd160(data); +} diff --git a/test/libsolidity/syntaxTests/constants/initialization/math_builtin_precompile_based_non_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/math_builtin_precompile_based_non_const_args.sol new file mode 100644 index 000000000000..fef5ccc88ca5 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/math_builtin_precompile_based_non_const_args.sol @@ -0,0 +1,10 @@ +contract A { + bytes data = hex"ffff"; + bytes32 constant sha = sha256(data); + bytes20 constant ripemd = ripemd160(data); + address constant addr = ecrecover("1234", 1, "0", abi.decode(data, (bytes2))); +} +// ---- +// TypeError 8349: (68-80): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (112-127): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (157-210): Initial value for constant variable has to be compile-time constant. diff --git a/test/libsolidity/syntaxTests/constants/mod_zero.sol b/test/libsolidity/syntaxTests/constants/initialization/modulo_by_zero.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/mod_zero.sol rename to test/libsolidity/syntaxTests/constants/initialization/modulo_by_zero.sol diff --git a/test/libsolidity/syntaxTests/constants/mulmod_zero.sol b/test/libsolidity/syntaxTests/constants/initialization/mulmod_by_zero.sol similarity index 100% rename from test/libsolidity/syntaxTests/constants/mulmod_zero.sol rename to test/libsolidity/syntaxTests/constants/initialization/mulmod_by_zero.sol diff --git a/test/libsolidity/syntaxTests/constants/initialization/string_concat_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/string_concat_const_args.sol new file mode 100644 index 000000000000..bc676d101573 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/string_concat_const_args.sol @@ -0,0 +1,9 @@ +string constant abcGlobal = string.concat("aaaa", "bbbb", "cccc"); + +contract A { + string public constant abc = string.concat("aaaa", "bbbb","cccc"); + + string public constant abcCopy = abc; + string public constant abcGlobalCopy = abcGlobal; + string public constant abcabc = string.concat(abc, abcGlobal); +} diff --git a/test/libsolidity/syntaxTests/constants/initialization/string_concat_non_const_args.sol b/test/libsolidity/syntaxTests/constants/initialization/string_concat_non_const_args.sol new file mode 100644 index 000000000000..f8b4aa6e29e7 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/string_concat_non_const_args.sol @@ -0,0 +1,14 @@ +contract A { + string name = "name"; + + function getName() public view returns (string memory) { + return name; + } + + string public constant abName = string.concat("aaaa", "bbbb", name); + + string public constant abgetName = string.concat("aaaa", "bbbb",getName()); +} +// ---- +// TypeError 8349: (165-200): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (242-281): Initial value for constant variable has to be compile-time constant. diff --git a/test/libsolidity/syntaxTests/constants/initialization/type_info.sol b/test/libsolidity/syntaxTests/constants/initialization/type_info.sol new file mode 100644 index 000000000000..51cfaa3a56e2 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/initialization/type_info.sol @@ -0,0 +1,23 @@ +string constant aNameGlobal = type(A).name; +bytes4 constant iNameGlobal = type(I).interfaceId; +uint256 constant minGlobal = type(uint256).min; +uint256 constant maxGlobal = type(uint256).max; +bytes constant creationCodeBGlobal = type(B).creationCode; +bytes constant runtimeCodeBGlobal = type(B).runtimeCode; + +contract B { +} + +interface I { + function hello() external pure; + function world(int) external pure; +} + +contract A { + string constant aName = type(A).name; + bytes4 constant iName = type(I).interfaceId; + uint256 constant min = type(uint256).min; + uint256 constant max = type(uint256).max; + bytes constant creationCodeB = type(B).creationCode; + bytes constant runtimeCodeB = type(B).runtimeCode; +} diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_bytes_concat.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_bytes_concat.sol index d341a5a764d2..77860af8ec0c 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_bytes_concat.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_bytes_concat.sol @@ -1,3 +1,3 @@ contract C layout at uint64(bytes8(bytes.concat("ABCD", "EFGH"))) {} // ---- -// TypeError 1139: (21-65): The base slot of the storage layout must be a compile-time constant expression. +// TypeError 1505: (21-65): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_kecak256.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_kecak256.sol index 539a59c11c07..0b35d60d891e 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_kecak256.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_kecak256.sol @@ -1,3 +1,3 @@ contract C layout at uint(keccak256(bytes.concat("ABCD"))) {} // ---- -// TypeError 1139: (21-58): The base slot of the storage layout must be a compile-time constant expression. +// TypeError 1505: (21-58): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.