diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 700f1be96..70ee17866 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,13 +5,11 @@ on: push: branches: - seismic - - veridise-audit + - merge-audits-final pull_request: branches: - # NOTE: seismic temporarily removed to avoid duplicate builds from veridise-audit→seismic PR. - # Re-enable after veridise-audit merges to seismic. - # - seismic - - veridise-audit + - seismic + - merge-audits-final concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} diff --git a/liblangutil/EVMVersion.cpp b/liblangutil/EVMVersion.cpp index c0c12274c..8908e3727 100644 --- a/liblangutil/EVMVersion.cpp +++ b/liblangutil/EVMVersion.cpp @@ -63,6 +63,7 @@ bool EVMVersion::hasOpcode(Instruction _opcode, std::optional _eofVersi return supportsTransientStorage(); case Instruction::CLOAD: case Instruction::CSTORE: + case Instruction::TIMESTAMPMS: return supportShieldedStorage() && !_eofVersion.has_value(); // Instructions below are deprecated in EOF case Instruction::CALL: diff --git a/liblangutil/EVMVersion.h b/liblangutil/EVMVersion.h index 2b367fdb2..f6e7310c5 100644 --- a/liblangutil/EVMVersion.h +++ b/liblangutil/EVMVersion.h @@ -148,6 +148,7 @@ class EVMVersion bool hasMcopy() const { return *this >= cancun(); } bool supportsTransientStorage() const { return *this >= cancun(); } bool supportShieldedStorage() const { return *this >= mercury(); } + bool hasTimestampMs() const { return *this >= mercury(); } bool supportsEOF() const { return *this >= firstWithEOF(); } bool hasOpcode(evmasm::Instruction _opcode, std::optional _eofVersion) const; diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index c52384e06..e8d4a5248 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -3718,6 +3718,18 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) _memberAccess.location(), "Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain." ); + else if (memberName == "timestamp_ms" && !m_evmVersion.hasTimestampMs()) + m_errorReporter.typeError( + 4521_error, + _memberAccess.location(), + "\"timestamp_ms\" is not supported by the VM version." + ); + else if (memberName == "timestamp_seconds" && !m_evmVersion.hasTimestampMs()) + m_errorReporter.typeError( + 8743_error, + _memberAccess.location(), + "\"timestamp_seconds\" is not supported by the VM version." + ); } } diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 6fe394384..6f790363e 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -933,7 +933,7 @@ void CompilerUtils::convertType( } else if (targetTypeCategory == Type::Category::Enum) { - solAssert((stackTypeCategory != Type::Category::Address || stackTypeCategory != Type::Category::ShieldedAddress), "Invalid conversion to EnumType requested."); + solAssert((stackTypeCategory != Type::Category::Address && stackTypeCategory != Type::Category::ShieldedAddress), "Invalid conversion to EnumType requested."); solAssert(_typeOnStack.mobileType()); // just clean convertType(_typeOnStack, *_typeOnStack.mobileType(), true); diff --git a/libsolidity/formal/Predicate.cpp b/libsolidity/formal/Predicate.cpp index 7f742ec18..649aea00d 100644 --- a/libsolidity/formal/Predicate.cpp +++ b/libsolidity/formal/Predicate.cpp @@ -252,6 +252,8 @@ std::string Predicate::formatSummaryCall( // TODO remove this for 0.9.0 if (magicKind == MagicType::Kind::Block && memberName == "difficulty") memberName = "prevrandao"; + if (magicKind == MagicType::Kind::Block && memberName == "timestamp_seconds") + memberName = "timestamp"; if (magicKind == MagicType::Kind::Block || magicKind == MagicType::Kind::Message || magicKind == MagicType::Kind::Transaction) txVars.insert(magicType->toString(true) + "." + memberName); diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index 57b155743..98b758781 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -1420,13 +1420,20 @@ bool SMTEncoder::visit(MemberAccess const& _memberAccess) // TODO remove this for 0.9.0 if (name == "block" && memberName == "difficulty") memberName = "prevrandao"; + if (name == "block" && memberName == "timestamp_seconds") + memberName = "timestamp"; defineExpr(_memberAccess, state().txMember(name + "." + memberName)); } else if (auto magicType = dynamic_cast(exprType)) { if (magicType->kind() == MagicType::Kind::Block) - defineExpr(_memberAccess, state().txMember("block." + _memberAccess.memberName())); + { + auto memberName = _memberAccess.memberName(); + if (memberName == "timestamp_seconds") + memberName = "timestamp"; + defineExpr(_memberAccess, state().txMember("block." + memberName)); + } else if (magicType->kind() == MagicType::Kind::Message) defineExpr(_memberAccess, state().txMember("msg." + _memberAccess.memberName())); else if (magicType->kind() == MagicType::Kind::Transaction) diff --git a/libsolidity/formal/SymbolicState.cpp b/libsolidity/formal/SymbolicState.cpp index 35828a3a3..4f290aaf9 100644 --- a/libsolidity/formal/SymbolicState.cpp +++ b/libsolidity/formal/SymbolicState.cpp @@ -235,7 +235,6 @@ smtutil::Expression SymbolicState::txTypeConstraints() const smt::symbolicUnknownConstraints(m_tx.member("block.number"), TypeProvider::uint256()) && smt::symbolicUnknownConstraints(m_tx.member("block.timestamp"), TypeProvider::uint256()) && smt::symbolicUnknownConstraints(m_tx.member("block.timestamp_ms"), TypeProvider::uint256()) && - smt::symbolicUnknownConstraints(m_tx.member("block.timestamp_seconds"), TypeProvider::uint256()) && smt::symbolicUnknownConstraints(m_tx.member("msg.sender"), TypeProvider::address()) && smt::symbolicUnknownConstraints(m_tx.member("msg.value"), TypeProvider::uint256()) && smt::symbolicUnknownConstraints(m_tx.member("tx.origin"), TypeProvider::address()) && diff --git a/libsolidity/formal/SymbolicTypes.cpp b/libsolidity/formal/SymbolicTypes.cpp index 19a9020f6..ca8f2ad31 100644 --- a/libsolidity/formal/SymbolicTypes.cpp +++ b/libsolidity/formal/SymbolicTypes.cpp @@ -686,7 +686,6 @@ std::map transactionMemberTypes() {"block.number", TypeProvider::uint256()}, {"block.timestamp", TypeProvider::uint256()}, {"block.timestamp_ms", TypeProvider::uint256()}, - {"block.timestamp_seconds", TypeProvider::uint256()}, {"blobhash", TypeProvider::array(DataLocation::Memory, TypeProvider::uint256())}, {"blockhash", TypeProvider::array(DataLocation::Memory, TypeProvider::uint256())}, {"msg.data", TypeProvider::bytesCalldata()}, diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index eefbb6cc2..c9d95f713 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -852,7 +852,7 @@ bool AsmAnalyzer::validateInstructions(evmasm::Instruction _instr, SourceLocatio errorForVM(7755_error, "only available for Cancun-compatible"); else if ((_instr == evmasm::Instruction::TSTORE || _instr == evmasm::Instruction::TLOAD) && !m_evmVersion.supportsTransientStorage()) errorForVM(6243_error, "only available for Cancun-compatible"); - else if ((_instr == evmasm::Instruction::CLOAD || _instr == evmasm::Instruction::CSTORE) && !m_evmVersion.supportShieldedStorage()) + else if ((_instr == evmasm::Instruction::CLOAD || _instr == evmasm::Instruction::CSTORE || _instr == evmasm::Instruction::TIMESTAMPMS) && !m_evmVersion.supportShieldedStorage()) errorForVM(6245_error, "only available for Mercury-compatible"); else if (_instr == evmasm::Instruction::PC) m_errorReporter.error( diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index b0a0c5878..a9eef4455 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -137,7 +137,7 @@ std::set> createReservedIdentifiers(langutil::EVMVersio { return _evmVersion < langutil::EVMVersion::mercury() && - (_instr == evmasm::Instruction::CSTORE || _instr == evmasm::Instruction::CLOAD); + (_instr == evmasm::Instruction::CSTORE || _instr == evmasm::Instruction::CLOAD || _instr == evmasm::Instruction::TIMESTAMPMS); }; auto eofIdentifiersException = [&](evmasm::Instruction _instr) -> bool diff --git a/test/cmdlineTests/shielded_sbytes16_via_ir/args b/test/cmdlineTests/shielded_sbytes16_via_ir/args new file mode 100644 index 000000000..9b1d485a3 --- /dev/null +++ b/test/cmdlineTests/shielded_sbytes16_via_ir/args @@ -0,0 +1 @@ +--asm --via-ir diff --git a/test/cmdlineTests/shielded_sbytes16_via_ir/input.sol b/test/cmdlineTests/shielded_sbytes16_via_ir/input.sol new file mode 100644 index 000000000..9c2f1ba91 --- /dev/null +++ b/test/cmdlineTests/shielded_sbytes16_via_ir/input.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; + +contract C { + sbytes16 data; + function test() external { + data = sbytes16(0); + } +} diff --git a/test/cmdlineTests/shielded_sbytes16_via_ir/output b/test/cmdlineTests/shielded_sbytes16_via_ir/output new file mode 100644 index 000000000..7fe68f6fb --- /dev/null +++ b/test/cmdlineTests/shielded_sbytes16_via_ir/output @@ -0,0 +1,231 @@ +Warning: This is a pre-release compiler version, please do not use it in production. + + +======= shielded_sbytes16_via_ir/input.sol:C ======= +EVM assembly: + /* "shielded_sbytes16_via_ir/input.sol":60:158 contract C {... */ + mstore(0x40, 0x80) + jumpi(tag_3, callvalue) + tag_5 + tag_1 + jump // in +tag_5: + dataSize(sub_0) + dataOffset(sub_0) + dup3 + codecopy + dataSize(sub_0) + swap1 + return +tag_3: + tag_2 + jump // in +tag_1: + mload(0x40) + swap1 + jump // out +tag_2: + 0x00 + dup1 + revert +stop + +sub_0: assembly { + /* "shielded_sbytes16_via_ir/input.sol":60:158 contract C {... */ + mstore(0x40, 0x80) + jumpi(tag_20, iszero(lt(calldatasize, 0x04))) + tag_21: + tag_8 + jump // in + tag_20: + tag_22 + calldataload(0x00) + tag_1 + jump // in + tag_22: + 0xf8a8fd6d + sub + tag_21 + jumpi + tag_7 + jump // in + tag_1: + 0xe0 + shr + swap1 + jump // out + tag_2: + mload(0x40) + swap1 + jump // out + tag_3: + 0x00 + dup1 + revert + tag_4: + 0x00 + dup1 + revert + tag_5: + 0x00 + swap2 + sub + slt + tag_25 + jumpi + jump // out + tag_25: + tag_4 + jump // in + tag_6: + 0x00 + add + swap1 + jump // out + tag_7: + jumpi(tag_27, callvalue) + tag_29 + calldatasize + 0x04 + tag_5 + jump // in + tag_29: + tag_30 + tag_19 + jump // in + tag_30: + tag_31 + tag_2 + jump // in + tag_31: + dup1 + tag_32 + dup2 + tag_6 + jump // in + tag_32: + sub + swap1 + return + tag_27: + tag_3 + jump // in + tag_8: + 0x00 + dup1 + revert + tag_9: + swap1 + jump // out + tag_10: + not(0xffffffffffffffffffffffffffffffff) + and + swap1 + jump // out + tag_11: + 0x80 + shl + swap1 + jump // out + tag_12: + tag_33 + tag_34 + tag_35 + swap3 + tag_9 + jump // in + tag_34: + tag_11 + jump // in + tag_33: + tag_10 + jump // in + tag_35: + swap1 + jump // out + tag_13: + 0x00 + shl + swap1 + jump // out + tag_14: + swap1 + tag_36 + not(0x00) + swap2 + tag_13 + jump // in + tag_36: + swap2 + dup2 + not + and + swap2 + and + or + swap1 + jump // out + tag_15: + tag_37 + swap1 + tag_10 + jump // in + tag_37: + swap1 + jump // out + tag_16: + 0x00 + shr + swap1 + jump // out + tag_17: + tag_38 + swap1 + tag_16 + jump // in + tag_38: + swap1 + jump // out + tag_18: + swap1 + tag_39 + tag_40 + tag_41 + swap3 + tag_15 + jump // in + tag_40: + tag_17 + jump // in + tag_39: + dup3 + cload + tag_14 + jump // in + tag_41: + swap1 + cstore + jump // out + /* "shielded_sbytes16_via_ir/input.sol":96:156 function test() external {... */ + tag_19: + /* "shielded_sbytes16_via_ir/input.sol":131:149 data = sbytes16(0) */ + tag_42 + /* "shielded_sbytes16_via_ir/input.sol":138:149 sbytes16(0) */ + tag_43 + /* "shielded_sbytes16_via_ir/input.sol":147:148 0 */ + 0x00 + /* "shielded_sbytes16_via_ir/input.sol":138:149 sbytes16(0) */ + tag_12 + jump // in + tag_43: + /* "shielded_sbytes16_via_ir/input.sol":131:149 data = sbytes16(0) */ + 0x00 + tag_18 + jump // in + tag_42: + /* "shielded_sbytes16_via_ir/input.sol":96:156 function test() external {... */ + jump // out + + auxdata: 0xa264697066735822122037b55db07a67fb1a37064c30080d17923eabae62f0cdd6d344db02a833c23ccb64736f6c63782c302e382e33312d646576656c6f702e323032362e312e32312b636f6d6d69742e38346365363530622e6d6f64005d +} + diff --git a/test/cmdlineTests/shielded_sbytes1_via_ir/args b/test/cmdlineTests/shielded_sbytes1_via_ir/args new file mode 100644 index 000000000..9b1d485a3 --- /dev/null +++ b/test/cmdlineTests/shielded_sbytes1_via_ir/args @@ -0,0 +1 @@ +--asm --via-ir diff --git a/test/cmdlineTests/shielded_sbytes1_via_ir/input.sol b/test/cmdlineTests/shielded_sbytes1_via_ir/input.sol new file mode 100644 index 000000000..9ce8ee6b7 --- /dev/null +++ b/test/cmdlineTests/shielded_sbytes1_via_ir/input.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; + +contract C { + sbytes1 data; + function test() external { + data = sbytes1(0); + } +} diff --git a/test/cmdlineTests/shielded_sbytes1_via_ir/output b/test/cmdlineTests/shielded_sbytes1_via_ir/output new file mode 100644 index 000000000..655823d28 --- /dev/null +++ b/test/cmdlineTests/shielded_sbytes1_via_ir/output @@ -0,0 +1,231 @@ +Warning: This is a pre-release compiler version, please do not use it in production. + + +======= shielded_sbytes1_via_ir/input.sol:C ======= +EVM assembly: + /* "shielded_sbytes1_via_ir/input.sol":60:156 contract C {... */ + mstore(0x40, 0x80) + jumpi(tag_3, callvalue) + tag_5 + tag_1 + jump // in +tag_5: + dataSize(sub_0) + dataOffset(sub_0) + dup3 + codecopy + dataSize(sub_0) + swap1 + return +tag_3: + tag_2 + jump // in +tag_1: + mload(0x40) + swap1 + jump // out +tag_2: + 0x00 + dup1 + revert +stop + +sub_0: assembly { + /* "shielded_sbytes1_via_ir/input.sol":60:156 contract C {... */ + mstore(0x40, 0x80) + jumpi(tag_20, iszero(lt(calldatasize, 0x04))) + tag_21: + tag_8 + jump // in + tag_20: + tag_22 + calldataload(0x00) + tag_1 + jump // in + tag_22: + 0xf8a8fd6d + sub + tag_21 + jumpi + tag_7 + jump // in + tag_1: + 0xe0 + shr + swap1 + jump // out + tag_2: + mload(0x40) + swap1 + jump // out + tag_3: + 0x00 + dup1 + revert + tag_4: + 0x00 + dup1 + revert + tag_5: + 0x00 + swap2 + sub + slt + tag_25 + jumpi + jump // out + tag_25: + tag_4 + jump // in + tag_6: + 0x00 + add + swap1 + jump // out + tag_7: + jumpi(tag_27, callvalue) + tag_29 + calldatasize + 0x04 + tag_5 + jump // in + tag_29: + tag_30 + tag_19 + jump // in + tag_30: + tag_31 + tag_2 + jump // in + tag_31: + dup1 + tag_32 + dup2 + tag_6 + jump // in + tag_32: + sub + swap1 + return + tag_27: + tag_3 + jump // in + tag_8: + 0x00 + dup1 + revert + tag_9: + swap1 + jump // out + tag_10: + shl(0xf8, 0xff) + and + swap1 + jump // out + tag_11: + 0xf8 + shl + swap1 + jump // out + tag_12: + tag_33 + tag_34 + tag_35 + swap3 + tag_9 + jump // in + tag_34: + tag_11 + jump // in + tag_33: + tag_10 + jump // in + tag_35: + swap1 + jump // out + tag_13: + 0x00 + shl + swap1 + jump // out + tag_14: + swap1 + tag_36 + not(0x00) + swap2 + tag_13 + jump // in + tag_36: + swap2 + dup2 + not + and + swap2 + and + or + swap1 + jump // out + tag_15: + tag_37 + swap1 + tag_10 + jump // in + tag_37: + swap1 + jump // out + tag_16: + 0x00 + shr + swap1 + jump // out + tag_17: + tag_38 + swap1 + tag_16 + jump // in + tag_38: + swap1 + jump // out + tag_18: + swap1 + tag_39 + tag_40 + tag_41 + swap3 + tag_15 + jump // in + tag_40: + tag_17 + jump // in + tag_39: + dup3 + cload + tag_14 + jump // in + tag_41: + swap1 + cstore + jump // out + /* "shielded_sbytes1_via_ir/input.sol":95:154 function test() external {... */ + tag_19: + /* "shielded_sbytes1_via_ir/input.sol":130:147 data = sbytes1(0) */ + tag_42 + /* "shielded_sbytes1_via_ir/input.sol":137:147 sbytes1(0) */ + tag_43 + /* "shielded_sbytes1_via_ir/input.sol":145:146 0 */ + 0x00 + /* "shielded_sbytes1_via_ir/input.sol":137:147 sbytes1(0) */ + tag_12 + jump // in + tag_43: + /* "shielded_sbytes1_via_ir/input.sol":130:147 data = sbytes1(0) */ + 0x00 + tag_18 + jump // in + tag_42: + /* "shielded_sbytes1_via_ir/input.sol":95:154 function test() external {... */ + jump // out + + auxdata: 0xa26469706673582212202b26554c6aa2658af95ca8a84ff072edd4a43ec2a47a56722a7cd769e7f53d5364736f6c63782c302e382e33312d646576656c6f702e323032362e312e32312b636f6d6d69742e38346365363530622e6d6f64005d +} + diff --git a/test/cmdlineTests/shielded_sbytes32_via_ir/args b/test/cmdlineTests/shielded_sbytes32_via_ir/args new file mode 100644 index 000000000..9b1d485a3 --- /dev/null +++ b/test/cmdlineTests/shielded_sbytes32_via_ir/args @@ -0,0 +1 @@ +--asm --via-ir diff --git a/test/cmdlineTests/shielded_sbytes32_via_ir/input.sol b/test/cmdlineTests/shielded_sbytes32_via_ir/input.sol new file mode 100644 index 000000000..585cdd245 --- /dev/null +++ b/test/cmdlineTests/shielded_sbytes32_via_ir/input.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; + +contract Blah { + sbytes32 data; + function test() external { + data = sbytes32(0); + } +} diff --git a/test/cmdlineTests/shielded_sbytes32_via_ir/output b/test/cmdlineTests/shielded_sbytes32_via_ir/output new file mode 100644 index 000000000..73bc40ef4 --- /dev/null +++ b/test/cmdlineTests/shielded_sbytes32_via_ir/output @@ -0,0 +1,224 @@ +Warning: This is a pre-release compiler version, please do not use it in production. + + +======= shielded_sbytes32_via_ir/input.sol:Blah ======= +EVM assembly: + /* "shielded_sbytes32_via_ir/input.sol":60:161 contract Blah {... */ + mstore(0x40, 0x80) + jumpi(tag_3, callvalue) + tag_5 + tag_1 + jump // in +tag_5: + dataSize(sub_0) + dataOffset(sub_0) + dup3 + codecopy + dataSize(sub_0) + swap1 + return +tag_3: + tag_2 + jump // in +tag_1: + mload(0x40) + swap1 + jump // out +tag_2: + 0x00 + dup1 + revert +stop + +sub_0: assembly { + /* "shielded_sbytes32_via_ir/input.sol":60:161 contract Blah {... */ + mstore(0x40, 0x80) + jumpi(tag_19, iszero(lt(calldatasize, 0x04))) + tag_20: + tag_8 + jump // in + tag_19: + tag_21 + calldataload(0x00) + tag_1 + jump // in + tag_21: + 0xf8a8fd6d + sub + tag_20 + jumpi + tag_7 + jump // in + tag_1: + 0xe0 + shr + swap1 + jump // out + tag_2: + mload(0x40) + swap1 + jump // out + tag_3: + 0x00 + dup1 + revert + tag_4: + 0x00 + dup1 + revert + tag_5: + 0x00 + swap2 + sub + slt + tag_24 + jumpi + jump // out + tag_24: + tag_4 + jump // in + tag_6: + 0x00 + add + swap1 + jump // out + tag_7: + jumpi(tag_26, callvalue) + tag_28 + calldatasize + 0x04 + tag_5 + jump // in + tag_28: + tag_29 + tag_18 + jump // in + tag_29: + tag_30 + tag_2 + jump // in + tag_30: + dup1 + tag_31 + dup2 + tag_6 + jump // in + tag_31: + sub + swap1 + return + tag_26: + tag_3 + jump // in + tag_8: + 0x00 + dup1 + revert + tag_9: + swap1 + jump // out + tag_10: + swap1 + jump // out + tag_11: + 0x00 + shl + swap1 + jump // out + tag_12: + tag_32 + tag_33 + tag_34 + swap3 + tag_9 + jump // in + tag_33: + tag_11 + jump // in + tag_32: + tag_10 + jump // in + tag_34: + swap1 + jump // out + tag_13: + swap1 + tag_35 + not(0x00) + swap2 + tag_11 + jump // in + tag_35: + swap2 + dup2 + not + and + swap2 + and + or + swap1 + jump // out + tag_14: + tag_36 + swap1 + tag_10 + jump // in + tag_36: + swap1 + jump // out + tag_15: + 0x00 + shr + swap1 + jump // out + tag_16: + tag_37 + swap1 + tag_15 + jump // in + tag_37: + swap1 + jump // out + tag_17: + swap1 + tag_38 + tag_39 + tag_40 + swap3 + tag_14 + jump // in + tag_39: + tag_16 + jump // in + tag_38: + dup3 + cload + tag_13 + jump // in + tag_40: + swap1 + cstore + jump // out + /* "shielded_sbytes32_via_ir/input.sol":99:159 function test() external {... */ + tag_18: + /* "shielded_sbytes32_via_ir/input.sol":134:152 data = sbytes32(0) */ + tag_41 + /* "shielded_sbytes32_via_ir/input.sol":141:152 sbytes32(0) */ + tag_42 + /* "shielded_sbytes32_via_ir/input.sol":150:151 0 */ + 0x00 + /* "shielded_sbytes32_via_ir/input.sol":141:152 sbytes32(0) */ + tag_12 + jump // in + tag_42: + /* "shielded_sbytes32_via_ir/input.sol":134:152 data = sbytes32(0) */ + 0x00 + tag_17 + jump // in + tag_41: + /* "shielded_sbytes32_via_ir/input.sol":99:159 function test() external {... */ + jump // out + + auxdata: 0xa26469706673582212207984999c96d771d415fc6fc5aa522d4585706eff88cb5b62f4075b6d9b472ae564736f6c63782c302e382e33312d646576656c6f702e323032362e312e32312b636f6d6d69742e38346365363530622e6d6f64005d +} + diff --git a/test/cmdlineTests/shielded_sbytes8_via_ir/args b/test/cmdlineTests/shielded_sbytes8_via_ir/args new file mode 100644 index 000000000..9b1d485a3 --- /dev/null +++ b/test/cmdlineTests/shielded_sbytes8_via_ir/args @@ -0,0 +1 @@ +--asm --via-ir diff --git a/test/cmdlineTests/shielded_sbytes8_via_ir/input.sol b/test/cmdlineTests/shielded_sbytes8_via_ir/input.sol new file mode 100644 index 000000000..54caeb286 --- /dev/null +++ b/test/cmdlineTests/shielded_sbytes8_via_ir/input.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; + +contract C { + sbytes8 data; + function test() external { + data = sbytes8(0); + } +} diff --git a/test/cmdlineTests/shielded_sbytes8_via_ir/output b/test/cmdlineTests/shielded_sbytes8_via_ir/output new file mode 100644 index 000000000..9dafafee9 --- /dev/null +++ b/test/cmdlineTests/shielded_sbytes8_via_ir/output @@ -0,0 +1,231 @@ +Warning: This is a pre-release compiler version, please do not use it in production. + + +======= shielded_sbytes8_via_ir/input.sol:C ======= +EVM assembly: + /* "shielded_sbytes8_via_ir/input.sol":60:156 contract C {... */ + mstore(0x40, 0x80) + jumpi(tag_3, callvalue) + tag_5 + tag_1 + jump // in +tag_5: + dataSize(sub_0) + dataOffset(sub_0) + dup3 + codecopy + dataSize(sub_0) + swap1 + return +tag_3: + tag_2 + jump // in +tag_1: + mload(0x40) + swap1 + jump // out +tag_2: + 0x00 + dup1 + revert +stop + +sub_0: assembly { + /* "shielded_sbytes8_via_ir/input.sol":60:156 contract C {... */ + mstore(0x40, 0x80) + jumpi(tag_20, iszero(lt(calldatasize, 0x04))) + tag_21: + tag_8 + jump // in + tag_20: + tag_22 + calldataload(0x00) + tag_1 + jump // in + tag_22: + 0xf8a8fd6d + sub + tag_21 + jumpi + tag_7 + jump // in + tag_1: + 0xe0 + shr + swap1 + jump // out + tag_2: + mload(0x40) + swap1 + jump // out + tag_3: + 0x00 + dup1 + revert + tag_4: + 0x00 + dup1 + revert + tag_5: + 0x00 + swap2 + sub + slt + tag_25 + jumpi + jump // out + tag_25: + tag_4 + jump // in + tag_6: + 0x00 + add + swap1 + jump // out + tag_7: + jumpi(tag_27, callvalue) + tag_29 + calldatasize + 0x04 + tag_5 + jump // in + tag_29: + tag_30 + tag_19 + jump // in + tag_30: + tag_31 + tag_2 + jump // in + tag_31: + dup1 + tag_32 + dup2 + tag_6 + jump // in + tag_32: + sub + swap1 + return + tag_27: + tag_3 + jump // in + tag_8: + 0x00 + dup1 + revert + tag_9: + swap1 + jump // out + tag_10: + shl(0xc0, 0xffffffffffffffff) + and + swap1 + jump // out + tag_11: + 0xc0 + shl + swap1 + jump // out + tag_12: + tag_33 + tag_34 + tag_35 + swap3 + tag_9 + jump // in + tag_34: + tag_11 + jump // in + tag_33: + tag_10 + jump // in + tag_35: + swap1 + jump // out + tag_13: + 0x00 + shl + swap1 + jump // out + tag_14: + swap1 + tag_36 + not(0x00) + swap2 + tag_13 + jump // in + tag_36: + swap2 + dup2 + not + and + swap2 + and + or + swap1 + jump // out + tag_15: + tag_37 + swap1 + tag_10 + jump // in + tag_37: + swap1 + jump // out + tag_16: + 0x00 + shr + swap1 + jump // out + tag_17: + tag_38 + swap1 + tag_16 + jump // in + tag_38: + swap1 + jump // out + tag_18: + swap1 + tag_39 + tag_40 + tag_41 + swap3 + tag_15 + jump // in + tag_40: + tag_17 + jump // in + tag_39: + dup3 + cload + tag_14 + jump // in + tag_41: + swap1 + cstore + jump // out + /* "shielded_sbytes8_via_ir/input.sol":95:154 function test() external {... */ + tag_19: + /* "shielded_sbytes8_via_ir/input.sol":130:147 data = sbytes8(0) */ + tag_42 + /* "shielded_sbytes8_via_ir/input.sol":137:147 sbytes8(0) */ + tag_43 + /* "shielded_sbytes8_via_ir/input.sol":145:146 0 */ + 0x00 + /* "shielded_sbytes8_via_ir/input.sol":137:147 sbytes8(0) */ + tag_12 + jump // in + tag_43: + /* "shielded_sbytes8_via_ir/input.sol":130:147 data = sbytes8(0) */ + 0x00 + tag_18 + jump // in + tag_42: + /* "shielded_sbytes8_via_ir/input.sol":95:154 function test() external {... */ + jump // out + + auxdata: 0xa264697066735822122019b1264fa2512459ee1fa9c98bdff7cce4a952bc9637da13537e7f43a55646f164736f6c63782c302e382e33312d646576656c6f702e323032362e312e32312b636f6d6d69742e38346365363530622e6d6f64005d +} + diff --git a/test/libsolidity/semanticTests/array/bytes_push_boundary_transition.sol b/test/libsolidity/semanticTests/array/bytes_push_boundary_transition.sol new file mode 100644 index 000000000..e645c1dd7 --- /dev/null +++ b/test/libsolidity/semanticTests/array/bytes_push_boundary_transition.sol @@ -0,0 +1,42 @@ +// Tests bytes.push() around the short/long array boundary (31 bytes) +// Regression test for storageArrayPushFunction bug +contract C { + bytes data; + + function pushByte(bytes1 b) public { + data.push(b); + } + + function getLength() public view returns (uint256) { + return data.length; + } + + function getByte(uint256 i) public view returns (bytes1) { + return data[i]; + } + + // Fill to exactly 30 bytes (still short array) + function fillTo30() public { + for (uint i = 0; i < 30; i++) { + data.push(bytes1(uint8(0x10 + i))); + } + } +} +// ---- +// getLength() -> 0 +// fillTo30() -> +// getLength() -> 30 +// getByte(uint256): 0 -> left(0x10) +// getByte(uint256): 29 -> left(0x2d) +// pushByte(bytes1): left(0xE1) -> +// getLength() -> 31 +// getByte(uint256): 30 -> left(0xE1) +// pushByte(bytes1): left(0xE2) -> +// getLength() -> 32 +// getByte(uint256): 31 -> left(0xE2) +// pushByte(bytes1): left(0xE3) -> +// getLength() -> 33 +// getByte(uint256): 32 -> left(0xE3) +// pushByte(bytes1): left(0xE4) -> +// getLength() -> 34 +// getByte(uint256): 33 -> left(0xE4) diff --git a/test/libsolidity/semanticTests/array/bytes_push_length_update.sol b/test/libsolidity/semanticTests/array/bytes_push_length_update.sol new file mode 100644 index 000000000..e52e02eef --- /dev/null +++ b/test/libsolidity/semanticTests/array/bytes_push_length_update.sol @@ -0,0 +1,37 @@ +// Tests that bytes.push(value) correctly updates length for long arrays +// Regression test: sload was used instead of sstore, failing to update length +contract C { + bytes data; + + function setup() public { + // Create a 64-byte array (well into long array territory) + for (uint i = 0; i < 64; i++) { + data.push(bytes1(uint8(i))); + } + } + + function pushAndReturnLength(bytes1 b) public returns (uint256) { + data.push(b); + return data.length; + } + + function getLength() public view returns (uint256) { + return data.length; + } + + function getByte(uint256 i) public view returns (bytes1) { + return data[i]; + } +} +// ---- +// setup() -> +// getLength() -> 64 +// pushAndReturnLength(bytes1): left(0xFF) -> 65 +// getLength() -> 65 +// getByte(uint256): 64 -> left(0xFF) +// pushAndReturnLength(bytes1): left(0xFE) -> 66 +// getLength() -> 66 +// getByte(uint256): 65 -> left(0xFE) +// pushAndReturnLength(bytes1): left(0xFD) -> 67 +// getLength() -> 67 +// getByte(uint256): 66 -> left(0xFD) diff --git a/test/libsolidity/semanticTests/array/bytes_push_long_array.sol b/test/libsolidity/semanticTests/array/bytes_push_long_array.sol new file mode 100644 index 000000000..608430255 --- /dev/null +++ b/test/libsolidity/semanticTests/array/bytes_push_long_array.sol @@ -0,0 +1,41 @@ +// Tests bytes.push(value) for long arrays (>31 bytes) +// Regression test for bug where sload was used instead of sstore +// and storeValue was missing template brackets in storageArrayPushFunction +contract C { + bytes data; + + // Fill array to exactly 32 bytes (transition to long array encoding) + function setup() public { + for (uint i = 0; i < 32; i++) { + data.push(bytes1(uint8(i))); + } + } + + // Push to long array - this exercises the buggy code path + function pushToLongArray(bytes1 b) public { + data.push(b); + } + + function getLength() public view returns (uint256) { + return data.length; + } + + function getByte(uint256 i) public view returns (bytes1) { + return data[i]; + } +} +// ---- +// getLength() -> 0 +// setup() -> +// getLength() -> 32 +// getByte(uint256): 0 -> left(0x00) +// getByte(uint256): 31 -> left(0x1f) +// pushToLongArray(bytes1): left(0xAA) -> +// getLength() -> 33 +// getByte(uint256): 32 -> left(0xAA) +// pushToLongArray(bytes1): left(0xBB) -> +// getLength() -> 34 +// getByte(uint256): 33 -> left(0xBB) +// pushToLongArray(bytes1): left(0xCC) -> +// getLength() -> 35 +// getByte(uint256): 34 -> left(0xCC) diff --git a/test/libsolidity/semanticTests/array/string_push_via_bytes.sol b/test/libsolidity/semanticTests/array/string_push_via_bytes.sol new file mode 100644 index 000000000..42a5ebb19 --- /dev/null +++ b/test/libsolidity/semanticTests/array/string_push_via_bytes.sol @@ -0,0 +1,40 @@ +// Tests string storage push via bytes cast for long strings +// Regression test for storageArrayPushFunction bug (affects isByteArrayOrString) +contract C { + string data; + + function setup() public { + // Create a 40-character string (long string encoding) + data = "1234567890123456789012345678901234567890"; + } + + function pushChar(bytes1 b) public { + bytes(data).push(b); + } + + function getLength() public view returns (uint256) { + return bytes(data).length; + } + + function getChar(uint256 i) public view returns (bytes1) { + return bytes(data)[i]; + } + + function getString() public view returns (string memory) { + return data; + } +} +// ---- +// setup() -> +// getLength() -> 40 +// getChar(uint256): 0 -> left(0x31) +// getChar(uint256): 39 -> left(0x30) +// pushChar(bytes1): left(0x41) -> +// getLength() -> 41 +// getChar(uint256): 40 -> left(0x41) +// pushChar(bytes1): left(0x42) -> +// getLength() -> 42 +// getChar(uint256): 41 -> left(0x42) +// pushChar(bytes1): left(0x43) -> +// getLength() -> 43 +// getChar(uint256): 42 -> left(0x43) diff --git a/test/libsolidity/semanticTests/inlineAssembly/cstore_then_sload_dynamic_slot_should_fail.sol b/test/libsolidity/semanticTests/inlineAssembly/cstore_then_sload_dynamic_slot_should_fail.sol new file mode 100644 index 000000000..78b0e7c02 --- /dev/null +++ b/test/libsolidity/semanticTests/inlineAssembly/cstore_then_sload_dynamic_slot_should_fail.sol @@ -0,0 +1,16 @@ +contract C { + function test(uint slot) external returns (uint) { + assembly { + cstore(0, 42) + } + // Separate block to avoid compile-time detection. + // When slot == 0, sload should revert because the slot is now private. + assembly { + let x := sload(slot) + mstore(0, x) + return(0, 32) + } + } +} +// ---- +// test(uint256): 0 -> FAILURE diff --git a/test/libsolidity/semanticTests/structs/shielded_struct_delete_mixed_fields.sol b/test/libsolidity/semanticTests/structs/shielded_struct_delete_mixed_fields.sol new file mode 100644 index 000000000..35093553d --- /dev/null +++ b/test/libsolidity/semanticTests/structs/shielded_struct_delete_mixed_fields.sol @@ -0,0 +1,17 @@ +contract C { + struct S { + uint8 a; + suint256 b; + } + + S s; + + function f() public returns (uint8) { + s.a = 42; + s.b = suint256(7); + delete s; + return s.a; + } +} +// ---- +// f() -> 0 diff --git a/test/libsolidity/semanticTests/structs/shielded_struct_delete_mixed_multiple_packed.sol b/test/libsolidity/semanticTests/structs/shielded_struct_delete_mixed_multiple_packed.sol new file mode 100644 index 000000000..406ac684e --- /dev/null +++ b/test/libsolidity/semanticTests/structs/shielded_struct_delete_mixed_multiple_packed.sol @@ -0,0 +1,21 @@ +contract C { + struct S { + uint8 a; + bool b; + suint256 c; + uint128 d; + } + + S s; + + function f() public returns (uint8, bool, uint128) { + s.a = 42; + s.b = true; + s.c = suint256(99); + s.d = 12345; + delete s; + return (s.a, s.b, s.d); + } +} +// ---- +// f() -> 0, false, 0 diff --git a/test/libsolidity/semanticTests/timestamps/timestamp_via_ir.sol b/test/libsolidity/semanticTests/timestamps/timestamp_via_ir.sol new file mode 100644 index 000000000..c280fd5f8 --- /dev/null +++ b/test/libsolidity/semanticTests/timestamps/timestamp_via_ir.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.0; + +// Test that block.timestamp_seconds and block.timestamp_ms work correctly +// when compiled via the IR pipeline. +contract C { + function getTimestamp() public view returns (uint256) { + return block.timestamp; + } + + function getTimestampMs() public view returns (uint256) { + return block.timestamp_ms; + } + + function getTimestampSeconds() public view returns (uint256) { + return block.timestamp_seconds; + } + + function checkTimestampEqualTimestampSeconds() public view returns (bool) { + return block.timestamp == block.timestamp_seconds; + } + + function checkTimestampMsGreaterThanTimestamp() public view returns (bool) { + return block.timestamp_ms >= block.timestamp * 1000; + } +} +// ==== +// compileViaYul: true +// ---- +// getTimestamp() -> 0x0f +// getTimestampMs() -> 0x7530 +// getTimestampSeconds() -> 0x2d +// checkTimestampEqualTimestampSeconds() -> true +// checkTimestampMsGreaterThanTimestamp() -> true diff --git a/test/libsolidity/semanticTests/userDefinedValueType/shielded_storage.sol b/test/libsolidity/semanticTests/userDefinedValueType/shielded_storage.sol new file mode 100644 index 000000000..8e7598f87 --- /dev/null +++ b/test/libsolidity/semanticTests/userDefinedValueType/shielded_storage.sol @@ -0,0 +1,53 @@ +// Test user-defined types wrapping shielded primitives correctly use cload/cstore +type MyShieldedUint is suint256; +type MyShieldedBool is sbool; +type MyShieldedAddress is saddress; +type MyShieldedBytes32 is sbytes32; + +contract C { + MyShieldedUint internal storedUint; + MyShieldedBool internal storedBool; + MyShieldedAddress internal storedAddress; + MyShieldedBytes32 internal storedBytes; + + function setUint(uint256 x) external { + storedUint = MyShieldedUint.wrap(suint256(x)); + } + + function getUint() external view returns (uint256) { + return uint256(MyShieldedUint.unwrap(storedUint)); + } + + function setBool(bool x) external { + storedBool = MyShieldedBool.wrap(sbool(x)); + } + + function getBool() external view returns (bool) { + return bool(MyShieldedBool.unwrap(storedBool)); + } + + function setAddress(address x) external { + storedAddress = MyShieldedAddress.wrap(saddress(x)); + } + + function getAddress() external view returns (address) { + return address(MyShieldedAddress.unwrap(storedAddress)); + } + + function setBytes(bytes32 x) external { + storedBytes = MyShieldedBytes32.wrap(sbytes32(x)); + } + + function getBytes() external view returns (bytes32) { + return bytes32(MyShieldedBytes32.unwrap(storedBytes)); + } +} +// ---- +// setUint(uint256): 42 -> +// getUint() -> 42 +// setBool(bool): true -> +// getBool() -> true +// setAddress(address): 0x1234567890123456789012345678901234567890 -> +// getAddress() -> 0x1234567890123456789012345678901234567890 +// setBytes(bytes32): 0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef -> +// getBytes() -> 0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef diff --git a/test/libsolidity/smtCheckerTests/special/timestamp_seconds.sol b/test/libsolidity/smtCheckerTests/special/timestamp_seconds.sol new file mode 100644 index 000000000..075c35572 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/special/timestamp_seconds.sol @@ -0,0 +1,16 @@ +contract C +{ + function f(uint timestamp_seconds) public view { + assert(block.timestamp_seconds == timestamp_seconds); // should fail + assert(block.timestamp == timestamp_seconds); // should fail + assert(block.timestamp == block.timestamp_seconds); // should hold + } +} +// ==== +// SMTEngine: all +// SMTIgnoreCex: yes +// EVMVersion: >=mercury +// ---- +// Warning 6328: (63-113): CHC: Assertion violation happens here. +// Warning 6328: (132-174): CHC: Assertion violation happens here. +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/shielded_cstore_caller_then_sload.sol b/test/libsolidity/syntaxTests/inlineAssembly/shielded_cstore_caller_then_sload.sol new file mode 100644 index 000000000..12e63554f --- /dev/null +++ b/test/libsolidity/syntaxTests/inlineAssembly/shielded_cstore_caller_then_sload.sol @@ -0,0 +1,14 @@ +// Audit regression: cstore with caller() value followed by sload on same literal slot +contract C { + event e(uint); + function test() external { + uint c; + assembly { + cstore(0, caller()) + c := sload(0) + } + emit e(c); + } +} +// ---- +// TypeError 5768: (234-242): Cannot use sload() on a slot that was previously written with cstore(). cstore() makes the slot private, and sload() cannot access private storage. Use cload() instead. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/shielded_cstore_then_sload_dynamic_slot_ok.sol b/test/libsolidity/syntaxTests/inlineAssembly/shielded_cstore_then_sload_dynamic_slot_ok.sol new file mode 100644 index 000000000..b466e3c90 --- /dev/null +++ b/test/libsolidity/syntaxTests/inlineAssembly/shielded_cstore_then_sload_dynamic_slot_ok.sol @@ -0,0 +1,12 @@ +// Known limitation: dynamic slot prevents compile-time detection. +// cstore(0, 0) then sload(slot) with dynamic slot cannot be matched statically. +// Will revert at runtime if slot == 0. +contract C { + function test(uint slot) external returns (uint c) { + assembly { + cstore(0, 0) + c := sload(slot) + } + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/inlineAssembly/shielded_cstore_then_sload_var_slot.sol b/test/libsolidity/syntaxTests/inlineAssembly/shielded_cstore_then_sload_var_slot.sol new file mode 100644 index 000000000..32334ef87 --- /dev/null +++ b/test/libsolidity/syntaxTests/inlineAssembly/shielded_cstore_then_sload_var_slot.sol @@ -0,0 +1,12 @@ +// Variable-based slot matching: same Yul variable for cstore and sload slots +contract C { + function test() external returns (uint c) { + assembly { + let s := 0 + cstore(s, 42) + c := sload(s) + } + } +} +// ---- +// TypeError 5768: (224-232): Cannot use sload() on a slot that was previously written with cstore(). cstore() makes the slot private, and sload() cannot access private storage. Use cload() instead. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/shielded_sload_on_udt_suint.sol b/test/libsolidity/syntaxTests/inlineAssembly/shielded_sload_on_udt_suint.sol new file mode 100644 index 000000000..6cf1b8f15 --- /dev/null +++ b/test/libsolidity/syntaxTests/inlineAssembly/shielded_sload_on_udt_suint.sol @@ -0,0 +1,12 @@ +type MyShieldedUint is suint256; + +contract C { + MyShieldedUint x; + function f() external view returns (uint256 result) { + assembly { + result := sload(x.slot) + } + } +} +// ---- +// TypeError 5765: (168-181): Cannot use sload() on shielded storage variable. Use cload() instead. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/shielded_sstore_on_udt_sbool.sol b/test/libsolidity/syntaxTests/inlineAssembly/shielded_sstore_on_udt_sbool.sol new file mode 100644 index 000000000..68c5e1a90 --- /dev/null +++ b/test/libsolidity/syntaxTests/inlineAssembly/shielded_sstore_on_udt_sbool.sol @@ -0,0 +1,12 @@ +type MyShieldedBool is sbool; + +contract C { + MyShieldedBool x; + function f() external { + assembly { + sstore(x.slot, 1) + } + } +} +// ---- +// TypeError 5765: (125-142): Cannot use sstore() on shielded storage variable. Use cstore() instead. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/shielded_sstore_on_udt_suint.sol b/test/libsolidity/syntaxTests/inlineAssembly/shielded_sstore_on_udt_suint.sol new file mode 100644 index 000000000..8d80723f9 --- /dev/null +++ b/test/libsolidity/syntaxTests/inlineAssembly/shielded_sstore_on_udt_suint.sol @@ -0,0 +1,12 @@ +type MyShieldedUint is suint256; + +contract C { + MyShieldedUint x; + function f() external { + assembly { + sstore(x.slot, 42) + } + } +} +// ---- +// TypeError 5765: (128-146): Cannot use sstore() on shielded storage variable. Use cstore() instead. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/133_address_to_enum_conversion_not_allowed.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/133_address_to_enum_conversion_not_allowed.sol new file mode 100644 index 000000000..316ec8d7c --- /dev/null +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/133_address_to_enum_conversion_not_allowed.sol @@ -0,0 +1,8 @@ +contract test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } + function f(address a) public pure returns (ActionChoices) { + return ActionChoices(a); + } +} +// ---- +// TypeError 9640: (155-171): Explicit type conversion not allowed from "address" to "enum test.ActionChoices". diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/shielded_133_saddress_to_enum_conversion_not_allowed.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/shielded_133_saddress_to_enum_conversion_not_allowed.sol new file mode 100644 index 000000000..b7ee33165 --- /dev/null +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/shielded_133_saddress_to_enum_conversion_not_allowed.sol @@ -0,0 +1,8 @@ +contract test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } + function f(saddress a) public pure returns (ActionChoices) { + return ActionChoices(a); + } +} +// ---- +// TypeError 9640: (156-172): Explicit type conversion not allowed from "saddress" to "enum test.ActionChoices". diff --git a/test/libsolidity/syntaxTests/types/magic_block_timestamp_ms.sol b/test/libsolidity/syntaxTests/types/magic_block_timestamp_ms.sol new file mode 100644 index 000000000..1adbc2405 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/magic_block_timestamp_ms.sol @@ -0,0 +1,14 @@ +contract C { + function f() public view returns (uint) { + return block.timestamp; + } + function g() public view returns (uint) { + return block.timestamp_ms; + } + function h() public view returns (uint) { + return block.timestamp_seconds; + } +} +// ==== +// EVMVersion: >=mercury +// ---- diff --git a/test/libsolidity/syntaxTests/types/magic_block_timestamp_ms_error.sol b/test/libsolidity/syntaxTests/types/magic_block_timestamp_ms_error.sol new file mode 100644 index 000000000..09862da32 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/magic_block_timestamp_ms_error.sol @@ -0,0 +1,16 @@ +contract C { + function f() public view returns (uint) { + return block.timestamp_ms; + } + function g() public view returns (uint ret) { + assembly { + ret := timestampms() + } + } +} +// ==== +// EVMVersion: =cancun +// ---- +// TypeError 4521: (74-92): "timestamp_ms" is not supported by the VM version. +// TypeError 6245: (188-199): The "timestampms" instruction is only available for Mercury-compatible VMs (you are currently compiling for "cancun"). +// DeclarationError 8678: (181-201): Variable count for assignment to "ret" does not match number of values (1 vs. 0) diff --git a/test/libsolidity/syntaxTests/types/magic_block_timestamp_seconds_error.sol b/test/libsolidity/syntaxTests/types/magic_block_timestamp_seconds_error.sol new file mode 100644 index 000000000..1584bca5a --- /dev/null +++ b/test/libsolidity/syntaxTests/types/magic_block_timestamp_seconds_error.sol @@ -0,0 +1,9 @@ +contract C { + function f() public view returns (uint) { + return block.timestamp_seconds; + } +} +// ==== +// EVMVersion: =cancun +// ---- +// TypeError 8743: (74-97): "timestamp_seconds" is not supported by the VM version. diff --git a/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_timestampms_disallowed_pure.sol b/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_timestampms_disallowed_pure.sol new file mode 100644 index 000000000..90dce372f --- /dev/null +++ b/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_timestampms_disallowed_pure.sol @@ -0,0 +1,9 @@ +contract C { + function f() public pure returns (uint256 tsMs) { + assembly { + tsMs := timestampms() + } + } +} +// ---- +// TypeError 2527: (106-119): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". diff --git a/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_timestampms_view.sol b/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_timestampms_view.sol new file mode 100644 index 000000000..d38e5417a --- /dev/null +++ b/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_timestampms_view.sol @@ -0,0 +1,9 @@ +contract C { + function f() public view returns (uint256 ts, uint256 tsMs) { + assembly { + ts := timestamp() + tsMs := timestampms() + } + } +} +// ---- diff --git a/test/libyul/yulSyntaxTests/cstore_cload_timestampms_as_identifiers_pre_mercury.yul b/test/libyul/yulSyntaxTests/cstore_cload_timestampms_as_identifiers_pre_mercury.yul new file mode 100644 index 000000000..395f7f85f --- /dev/null +++ b/test/libyul/yulSyntaxTests/cstore_cload_timestampms_as_identifiers_pre_mercury.yul @@ -0,0 +1,7 @@ +{ + function cstore() {} + function cload() {} + function timestampms() {} +} +// ==== +// EVMVersion: =mercury +// ---- +// ParserError 5568: (15-26): Cannot use builtin function name "timestampms" as identifier name. diff --git a/test/libyul/yulSyntaxTests/timestampms_evm_version.yul b/test/libyul/yulSyntaxTests/timestampms_evm_version.yul new file mode 100644 index 000000000..4fa9a9163 --- /dev/null +++ b/test/libyul/yulSyntaxTests/timestampms_evm_version.yul @@ -0,0 +1,7 @@ +{ + let x := timestampms() +} +// ==== +// EVMVersion: