From 121cd1b1fe3d39c049854c19feedfbfebb53e172 Mon Sep 17 00:00:00 2001 From: Asuka Date: Tue, 28 Jul 2026 11:02:37 +0800 Subject: [PATCH 1/7] fix: gate experimental and unsupported VM targets --- liblangutil/EVMVersion.cpp | 18 ++++++++ libsolidity/analysis/TypeChecker.cpp | 38 +++++++++++++++++ libsolidity/interface/StandardCompiler.cpp | 15 ++++++- test/CMakeLists.txt | 1 + .../input.json | 1 + .../input.json | 1 + .../standard_no_append_cbor/input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 1 + .../input.json | 12 ++++++ .../output.json | 16 ++++++++ .../standard_viair_requested/input.json | 3 +- .../standard_yul_cfg_json_export/input.json | 1 + test/liblangutil/EVMVersion.cpp | 41 +++++++++++++++++++ .../tron/precompiles_before_byzantium.sol | 11 +++++ 30 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 test/cmdlineTests/standard_viair_experimental_warning/input.json create mode 100644 test/cmdlineTests/standard_viair_experimental_warning/output.json create mode 100644 test/liblangutil/EVMVersion.cpp create mode 100644 test/libsolidity/syntaxTests/tron/precompiles_before_byzantium.sol diff --git a/liblangutil/EVMVersion.cpp b/liblangutil/EVMVersion.cpp index 4fbfe8de41b0..dae910af38e7 100644 --- a/liblangutil/EVMVersion.cpp +++ b/liblangutil/EVMVersion.cpp @@ -61,6 +61,24 @@ bool EVMVersion::hasOpcode(Instruction _opcode, std::optional _eofVersi case Instruction::TSTORE: case Instruction::TLOAD: return supportsTransientStorage(); + // TRON-specific instructions are not part of the EOF instruction set. + case Instruction::CALLTOKEN: + case Instruction::TOKENBALANCE: + case Instruction::CALLTOKENVALUE: + case Instruction::CALLTOKENID: + case Instruction::ISCONTRACT: + case Instruction::NATIVEFREEZE: + case Instruction::NATIVEUNFREEZE: + case Instruction::NATIVEFREEZEEXPIRETIME: + case Instruction::NATIVEVOTE: + case Instruction::NATIVEWITHDRAWREWARD: + case Instruction::NATIVEFREEZEBALANCEV2: + case Instruction::NATIVEUNFREEZEBALANCEV2: + case Instruction::NATIVECANCELALLUNFREEZEV2: + case Instruction::NATIVEWITHDRAWEXPIREUNFREEZE: + case Instruction::NATIVEDELEGATERESOURCE: + case Instruction::NATIVEUNDELEGATERESOURCE: + return !_eofVersion.has_value(); // Instructions below are deprecated in EOF case Instruction::CALL: case Instruction::CALLCODE: diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 5c8c53613482..0ce058809cdd 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1999,6 +1999,38 @@ void TypeChecker::typeCheckFunctionCall( "\"staticcall\" is not supported by the VM version." ); + static std::set const tronStaticCallKinds = { + FunctionType::Kind::ValidateMultiSign, + FunctionType::Kind::BatchValidateSign, + FunctionType::Kind::VerifyBurnProof, + FunctionType::Kind::VerifyTransferProof, + FunctionType::Kind::VerifyMintProof, + FunctionType::Kind::PedersenHash, + FunctionType::Kind::RewardBalance, + FunctionType::Kind::IsSrCandidate, + FunctionType::Kind::VoteCount, + FunctionType::Kind::UsedVoteCount, + FunctionType::Kind::ReceivedVoteCount, + FunctionType::Kind::TotalVoteCount, + FunctionType::Kind::GetChainParameter, + FunctionType::Kind::AvailableUnfreezeV2Size, + FunctionType::Kind::UnfreezableBalanceV2, + FunctionType::Kind::ExpireUnfreezeBalanceV2, + FunctionType::Kind::DelegatableResource, + FunctionType::Kind::ResourceV2, + FunctionType::Kind::CheckUnDelegateResource, + FunctionType::Kind::ResourceUsage, + FunctionType::Kind::TotalResource, + FunctionType::Kind::TotalDelegatedResource, + FunctionType::Kind::TotalAcquiredResource, + }; + if (!m_evmVersion.hasStaticCall() && tronStaticCallKinds.count(_functionType->kind())) + m_errorReporter.typeError( + 9137_error, + _functionCall.location(), + "This TRON builtin requires a Byzantium-compatible VM." + ); + // Perform standard function call type checking typeCheckFunctionGeneralChecks(_functionCall, _functionType); } @@ -3290,6 +3322,12 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) { if (magicType->kind() == MagicType::Kind::ABI) annotation.isPure = true; + else if (magicType->kind() == MagicType::Kind::Chain && !m_evmVersion.hasStaticCall()) + m_errorReporter.typeError( + 9137_error, + _memberAccess.location(), + "This TRON builtin requires a Byzantium-compatible VM." + ); else if (magicType->kind() == MagicType::Kind::MetaType && ( memberName == "creationCode" || memberName == "runtimeCode" )) diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 85495a9e37e2..f5f737310c0d 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -430,7 +430,7 @@ std::optional checkAuxiliaryInputKeys(Json const& _input) std::optional checkSettingsKeys(Json const& _input) { - static std::set keys{"debug", "evmVersion", "eofVersion", "libraries", "metadata", "modelChecker", "optimizer", "outputSelection", "remappings", "stopAfter", "viaIR"}; + static std::set keys{"debug", "evmVersion", "eofVersion", "experimentalViaIR", "libraries", "metadata", "modelChecker", "optimizer", "outputSelection", "remappings", "stopAfter", "viaIR"}; return checkKeys(_input, keys, "settings"); } @@ -820,6 +820,19 @@ std::variant StandardCompiler::parseI return formatFatalError(Error::Type::JSONError, "\"settings.viaIR\" must be a Boolean."); ret.viaIR = settings["viaIR"].get(); } + bool experimentalViaIRAcknowledged = false; + if (settings.contains("experimentalViaIR")) + { + if (!settings["experimentalViaIR"].is_boolean()) + return formatFatalError(Error::Type::JSONError, "\"settings.experimentalViaIR\" must be a Boolean."); + experimentalViaIRAcknowledged = settings["experimentalViaIR"].get(); + } + if (ret.viaIR && !experimentalViaIRAcknowledged) + ret.errors.emplace_back(formatError( + Error::Type::Warning, + "general", + "The via-IR pipeline is experimental in the TRON Solidity compiler. Set \"settings.experimentalViaIR\" to true to acknowledge this and suppress this warning." + )); if (settings.contains("evmVersion")) { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index dbbcf3eaec81..8af881053fa6 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -63,6 +63,7 @@ detect_stray_source_files("${libevmasm_sources}" "libevmasm/") set(liblangutil_sources liblangutil/CharStream.cpp + liblangutil/EVMVersion.cpp liblangutil/Scanner.cpp liblangutil/SourceLocation.cpp ) diff --git a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/input.json b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/input.json index 6ff7662901e4..c306a4e01687 100644 --- a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/input.json +++ b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/input.json @@ -14,6 +14,7 @@ "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": true }, "outputSelection": diff --git a/test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/input.json b/test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/input.json index 06b89d0e01bf..d93f78f4d145 100644 --- a/test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/input.json +++ b/test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/input.json @@ -7,6 +7,7 @@ "outputSelection": {"*": {"*": ["ir"]}}, "optimizer": {"enabled": true}, "viaIR": true, + "experimentalViaIR": true, "debug": {"debugInfo": []} } } diff --git a/test/cmdlineTests/standard_no_append_cbor/input.json b/test/cmdlineTests/standard_no_append_cbor/input.json index 493325506dda..8fefb3ee0f50 100644 --- a/test/cmdlineTests/standard_no_append_cbor/input.json +++ b/test/cmdlineTests/standard_no_append_cbor/input.json @@ -10,6 +10,7 @@ "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": true }, diff --git a/test/cmdlineTests/standard_no_append_cbor_with_metadata_hash/input.json b/test/cmdlineTests/standard_no_append_cbor_with_metadata_hash/input.json index f12e45bf2fa9..a1652b5633d9 100644 --- a/test/cmdlineTests/standard_no_append_cbor_with_metadata_hash/input.json +++ b/test/cmdlineTests/standard_no_append_cbor_with_metadata_hash/input.json @@ -10,6 +10,7 @@ "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": true }, diff --git a/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json b/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json index 422a54f90d9f..aff5263670d6 100644 --- a/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json +++ b/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "debug": { "debugInfo": [ "ethdebug" diff --git a/test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/input.json b/test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/input.json index 8f8edcd29203..8fac23d615d9 100644 --- a/test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/input.json +++ b/test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "debug": { "debugInfo": [ "ethdebug" diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json index 8ed44ca05de2..15d1cd6ace39 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": false }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json index 27c400f9e946..add6ead1e0a0 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": false }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/input.json index ad74649f5d1d..9394bea47fc3 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": true }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/input.json index ad74649f5d1d..9394bea47fc3 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": true }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json index 35c8f940e82d..9a0d64f088a5 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": false }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json index e4681967f7db..028e195d408c 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": false }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json index 6239a7275e4d..4df522786b38 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": false }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json index fdb6c95b813e..1929a6a97ccd 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": false }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json index 5bc9d5467345..279c7ef44848 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "outputSelection": { "*": { "*": [ diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json index 8952a241f6e7..e87a97e5bb08 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "outputSelection": { "*": { "*": [ diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/input.json index a684e0dc073b..641dcfb1827e 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": true }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/input.json index 1f09e3a70253..c743d1609f2c 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/input.json @@ -10,6 +10,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "optimizer": { "enabled": true }, diff --git a/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json b/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json index dc86ac68494e..d2490aef88f6 100644 --- a/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json +++ b/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json @@ -5,6 +5,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "outputSelection": { "*": {"*": ["evm.bytecode"]} } diff --git a/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/input.json b/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/input.json index dc86ac68494e..d2490aef88f6 100644 --- a/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/input.json +++ b/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/input.json @@ -5,6 +5,7 @@ }, "settings": { "viaIR": true, + "experimentalViaIR": true, "outputSelection": { "*": {"*": ["evm.bytecode"]} } diff --git a/test/cmdlineTests/standard_viair_experimental_warning/input.json b/test/cmdlineTests/standard_viair_experimental_warning/input.json new file mode 100644 index 000000000000..0b05d0d0e7cd --- /dev/null +++ b/test/cmdlineTests/standard_viair_experimental_warning/input.json @@ -0,0 +1,12 @@ +{ + "language": "Solidity", + "sources": { + "A.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.0; contract A {}" + } + }, + "settings": { + "viaIR": true, + "outputSelection": {} + } +} diff --git a/test/cmdlineTests/standard_viair_experimental_warning/output.json b/test/cmdlineTests/standard_viair_experimental_warning/output.json new file mode 100644 index 000000000000..c74bd9d6b3a5 --- /dev/null +++ b/test/cmdlineTests/standard_viair_experimental_warning/output.json @@ -0,0 +1,16 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "The via-IR pipeline is experimental in the TRON Solidity compiler. Set \"settings.experimentalViaIR\" to true to acknowledge this and suppress this warning.", + "message": "The via-IR pipeline is experimental in the TRON Solidity compiler. Set \"settings.experimentalViaIR\" to true to acknowledge this and suppress this warning.", + "severity": "warning", + "type": "Warning" + } + ], + "sources": { + "A.sol": { + "id": 0 + } + } +} diff --git a/test/cmdlineTests/standard_viair_requested/input.json b/test/cmdlineTests/standard_viair_requested/input.json index 76ae807a615c..542b0372d6b0 100644 --- a/test/cmdlineTests/standard_viair_requested/input.json +++ b/test/cmdlineTests/standard_viair_requested/input.json @@ -16,6 +16,7 @@ { "*": { "*": ["ir", "evm.bytecode.object", "evm.bytecode.generatedSources", "evm.deployedBytecode.object"] } }, - "viaIR": true + "viaIR": true, + "experimentalViaIR": true } } diff --git a/test/cmdlineTests/standard_yul_cfg_json_export/input.json b/test/cmdlineTests/standard_yul_cfg_json_export/input.json index b5353721ee09..545bf50ae705 100644 --- a/test/cmdlineTests/standard_yul_cfg_json_export/input.json +++ b/test/cmdlineTests/standard_yul_cfg_json_export/input.json @@ -8,6 +8,7 @@ "enabled": true }, "viaIR": true, + "experimentalViaIR": true, "outputSelection": {"*": {"*": ["yulCFGJson"]}} } } diff --git a/test/liblangutil/EVMVersion.cpp b/test/liblangutil/EVMVersion.cpp new file mode 100644 index 000000000000..930ed4caaceb --- /dev/null +++ b/test/liblangutil/EVMVersion.cpp @@ -0,0 +1,41 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#include +#include + +#include + +namespace solidity::langutil::test +{ + +BOOST_AUTO_TEST_SUITE(EVMVersionTest) + +BOOST_AUTO_TEST_CASE(tron_instructions_are_not_available_in_eof) +{ + for (unsigned opcode = 0xd0; opcode <= 0xdf; ++opcode) + { + auto const instruction = static_cast(opcode); + BOOST_TEST(EVMVersion::osaka().hasOpcode(instruction, std::nullopt)); + BOOST_TEST(!EVMVersion::osaka().hasOpcode(instruction, 1)); + } +} + +BOOST_AUTO_TEST_SUITE_END() + +} diff --git a/test/libsolidity/syntaxTests/tron/precompiles_before_byzantium.sol b/test/libsolidity/syntaxTests/tron/precompiles_before_byzantium.sol new file mode 100644 index 000000000000..34b9a3b1587f --- /dev/null +++ b/test/libsolidity/syntaxTests/tron/precompiles_before_byzantium.sol @@ -0,0 +1,11 @@ +contract C { + function f() public view returns (bool, uint64) { + bool valid = validatemultisign(address(0), 0, bytes32(0), new bytes[](0)); + return (valid, chain.totalNetLimit); + } +} +// ==== +// EVMVersion: Date: Tue, 28 Jul 2026 11:06:03 +0800 Subject: [PATCH 2/7] fix: align TRON builtin semantics across backends --- libsolidity/analysis/GlobalContext.cpp | 2 +- libsolidity/ast/Types.cpp | 1 - libsolidity/codegen/ExpressionCompiler.cpp | 1 + .../codegen/ir/IRGeneratorForStatements.cpp | 35 ++++++++++++------ test/libsolidity/StandardCompiler.cpp | 36 +++++++++++++++++++ .../tron/validatemultisign_mutability.sol | 7 ++++ 6 files changed, 70 insertions(+), 12 deletions(-) create mode 100644 test/libsolidity/syntaxTests/tron/validatemultisign_mutability.sol diff --git a/libsolidity/analysis/GlobalContext.cpp b/libsolidity/analysis/GlobalContext.cpp index c186ad1a0f1b..b9666889cfeb 100644 --- a/libsolidity/analysis/GlobalContext.cpp +++ b/libsolidity/analysis/GlobalContext.cpp @@ -379,7 +379,7 @@ void GlobalContext::addValidateMultiSignMethod() { parameterNames, returnParameterNames, FunctionType::Kind::ValidateMultiSign, - StateMutability::Pure, + StateMutability::View, nullptr) )); } diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 46086f8f5d62..13fb93c3463b 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -3875,7 +3875,6 @@ bool FunctionType::isPure() const return m_kind == Kind::KECCAK256 || m_kind == Kind::ECRecover || - m_kind == Kind::ValidateMultiSign || m_kind == Kind::BatchValidateSign || m_kind == Kind::VerifyBurnProof || m_kind == Kind::VerifyTransferProof || diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 768895a31f7c..0704d83e240a 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -3319,6 +3319,7 @@ void ExpressionCompiler::appendExternalFunctionCall( switch v case 0 { v := 0x60 } default { + if mod(returndatasize(), 0x20) { revert(0, 0) } v := mload(0x40) mstore(0x40, add(v, and(add(returndatasize(), 0x3f), not(0x1f)))) mstore(v, div(returndatasize(), 0x20)) diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 9eb3f379378c..862ff7c9f592 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -1658,7 +1658,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) std::string tokenId{expressionAsType(*arguments[1], *(parameterTypes[1]))}; Whiskers templ(R"( if iszero(lt(0xf4240, )) { revert(0, 0) } - if iszero(gt(exp(2, 63), )) { revert(0, 0) } + if iszero(gt(0x8000000000000000, )) { revert(0, 0) } let := 0 if iszero() { := } let := calltoken(,
, , , 0, 0, 0, 0) @@ -1682,7 +1682,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) std::string tokenId{expressionAsType(*arguments[0], *(parameterTypes[0]))}; Whiskers templ(R"( if iszero(lt(0xf4240, )) { revert(0, 0) } - if iszero(gt(exp(2, 63), )) { revert(0, 0) } + if iszero(gt(0x8000000000000000, )) { revert(0, 0) } let := tokenbalance(,
) )"); templ("address", address); @@ -2004,30 +2004,41 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) let := staticcall(gas(),
, , sub(, ), , ) if iszero() { () } + + if lt(returndatasize(), 0x20) { + mstore(, 0) + returndatacopy(, 0, returndatasize()) + } + - + + if mod(returndatasize(), 0x20) { revert(0, 0) } let := add(returndatasize(), 0x40) returndatacopy(add(, 0x40), 0, returndatasize()) mstore(, 0x20) mstore(add(, 0x20), div(returndatasize(), 0x20)) - + let := returndatasize() returndatacopy(, 0, ) - + let := - + if gt(, returndatasize()) { := returndatasize() } - + // update freeMemoryPointer according to dynamic return size (, ) - let := (, add(, )) + + let := mload() + + let := (, add(, )) + )"); templ("allocateUnbounded", m_utils.allocateUnboundedFunction()); templ("pos", m_context.newYulVariable()); @@ -2040,12 +2051,16 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) if (returnInfo.dynamicReturnSize) solAssert(m_context.evmVersion().supportsReturndata()); - templ("supportsReturnData", m_context.evmVersion().supportsReturndata()); + bool const isLegacyCompatibleMultisig = + functionType->kind() == FunctionType::Kind::ValidateMultiSign || + functionType->kind() == FunctionType::Kind::BatchValidateSign; + templ("isLegacyCompatibleMultisig", isLegacyCompatibleMultisig); + templ("strictReturnSize", m_context.evmVersion().supportsReturndata() && !isLegacyCompatibleMultisig); templ("returnDataSizeVar", m_context.newYulVariable()); templ("staticReturndataSize", std::to_string(returnInfo.estimatedReturnSize)); templ("isReturndataSizeDynamic", returnInfo.dynamicReturnSize); - templ("isMintProof",functionType->kind() == FunctionType::Kind::VerifyMintProof ||functionType->kind() == FunctionType::Kind::VerifyTransferProof); + templ("isProof", functionType->kind() == FunctionType::Kind::VerifyMintProof || functionType->kind() == FunctionType::Kind::VerifyTransferProof); templ("finalizeAllocation", m_utils.finalizeAllocationFunction()); templ("retVars", IRVariable(_functionCall).commaSeparatedList()); templ("abiDecode", m_context.abiFunctions().tupleDecoder(returnInfo.returnTypes, true)); diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index 5360a2778677..60533522e36b 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -598,6 +598,42 @@ BOOST_AUTO_TEST_CASE(basic_compilation) ); } +BOOST_AUTO_TEST_CASE(tron_builtin_via_ir_codegen_guards) +{ + Json input = createLanguageAndSourcesSection("Solidity", {{"A.sol", R"( +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.30; +contract C { + function validate(address account, bytes32 content, bytes[] memory signatures) public view returns (bool) { + return validatemultisign(account, 0, content, signatures); + } + function transfer(address payable target, uint256 value, trcToken tokenId) public { + target.transferToken(value, tokenId); + } + function mint( + bytes32[9] memory output, + bytes32[2] memory bindingSignature, + uint64 value, + bytes32 signHash, + bytes32[33] memory frontier, + uint256 leafCount + ) public pure returns (bytes32[] memory) { + return verifyMintProof(output, bindingSignature, value, signHash, frontier, leafCount); + } +} +)"}}); + input["settings"]["viaIR"] = true; + input["settings"]["outputSelection"]["*"]["*"] = Json::array({"ir"}); + + Json const output = compile(input.dump()); + BOOST_REQUIRE(containsAtMostWarnings(output)); + std::string const ir = output["contracts"]["A.sol"]["C"]["ir"].get(); + BOOST_TEST(ir.find("if iszero(gt(0x8000000000000000") != std::string::npos); + BOOST_TEST(ir.find("exp(2, 63)") == std::string::npos); + BOOST_TEST(ir.find("if lt(returndatasize(), 0x20)") != std::string::npos); + BOOST_TEST(ir.find("if mod(returndatasize(), 0x20) { revert(0, 0) }") != std::string::npos); +} + BOOST_AUTO_TEST_CASE(compilation_error) { char const* input = R"( diff --git a/test/libsolidity/syntaxTests/tron/validatemultisign_mutability.sol b/test/libsolidity/syntaxTests/tron/validatemultisign_mutability.sol new file mode 100644 index 000000000000..3be19672eb7d --- /dev/null +++ b/test/libsolidity/syntaxTests/tron/validatemultisign_mutability.sol @@ -0,0 +1,7 @@ +contract C { + function f() public pure returns (bool) { + return validatemultisign(address(0), 0, bytes32(0), new bytes[](0)); + } +} +// ---- +// TypeError 2527: (74-134): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". From 5ff386e2f5d91011a4cbacb7285335200a8e0a18 Mon Sep 17 00:00:00 2001 From: Asuka Date: Tue, 28 Jul 2026 11:27:32 +0800 Subject: [PATCH 3/7] chore(codegen): assert TRON builtin arities --- libsolidity/codegen/ExpressionCompiler.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 0704d83e240a..92db9d9589d9 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -1646,6 +1646,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) break; case FunctionType::Kind::Freeze: { + solAssert(arguments.size() == 2 && function.parameterTypes().size() == 2, ""); _functionCall.expression().accept(*this); for (unsigned i = 0; i < arguments.size(); ++i){ acceptAndConvert(*arguments[i], *function.parameterTypes()[i]); @@ -1657,6 +1658,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) } case FunctionType::Kind::Unfreeze: { + solAssert(arguments.size() == 1 && function.parameterTypes().size() == 1, ""); _functionCall.expression().accept(*this); for (unsigned i = 0; i < arguments.size(); ++i) { @@ -1669,6 +1671,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) } case FunctionType::Kind::FreezeExpireTime: { + solAssert(arguments.size() == 1 && function.parameterTypes().size() == 1, ""); _functionCall.expression().accept(*this); for (unsigned i = 0; i < arguments.size(); ++i) { @@ -1679,6 +1682,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) } case FunctionType::Kind::Vote: { + solAssert(arguments.size() == 2 && function.parameterTypes().size() == 2, ""); _functionCall.expression().accept(*this); for (unsigned i = 0; i < arguments.size(); ++i) { @@ -1692,11 +1696,13 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) } case FunctionType::Kind::WithdrawReward: { + solAssert(arguments.empty() && function.parameterTypes().empty(), ""); m_context << Instruction::NATIVEWITHDRAWREWARD; break; } case FunctionType::Kind::FreezeBalanceV2: { + solAssert(arguments.size() == 2 && function.parameterTypes().size() == 2, ""); _functionCall.expression().accept(*this); for (unsigned i = 0; i < arguments.size(); ++i){ acceptAndConvert(*arguments[i], *function.parameterTypes()[i]); @@ -1708,6 +1714,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) } case FunctionType::Kind::UnfreezeBalanceV2: { + solAssert(arguments.size() == 2 && function.parameterTypes().size() == 2, ""); _functionCall.expression().accept(*this); for (unsigned i = 0; i < arguments.size(); ++i){ acceptAndConvert(*arguments[i], *function.parameterTypes()[i]); @@ -1719,16 +1726,19 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) } case FunctionType::Kind::CancelAllUnfreezeV2: { + solAssert(arguments.empty() && function.parameterTypes().empty(), ""); m_context << Instruction::NATIVECANCELALLUNFREEZEV2; break; } case FunctionType::Kind::WithdrawExpireUnfreeze: { + solAssert(arguments.empty() && function.parameterTypes().empty(), ""); m_context << Instruction::NATIVEWITHDRAWEXPIREUNFREEZE; break; } case FunctionType::Kind::DelegateResource: { + solAssert(arguments.size() == 2 && function.parameterTypes().size() == 2, ""); _functionCall.expression().accept(*this); for (unsigned i = 0; i < arguments.size(); ++i){ acceptAndConvert(*arguments[i], *function.parameterTypes()[i]); @@ -1740,6 +1750,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) } case FunctionType::Kind::UnDelegateResource: { + solAssert(arguments.size() == 2 && function.parameterTypes().size() == 2, ""); _functionCall.expression().accept(*this); for (unsigned i = 0; i < arguments.size(); ++i){ acceptAndConvert(*arguments[i], *function.parameterTypes()[i]); From 447974f35c8f3ad1910ec3c2994e9cfbef0f67f8 Mon Sep 17 00:00:00 2001 From: Asuka Date: Tue, 28 Jul 2026 11:14:36 +0800 Subject: [PATCH 4/7] fix(abi): restrict TRON address prefixes --- libsolidity/codegen/YulUtilFunctions.cpp | 4 +++- .../semanticTests/abiEncoderV2/cleanup/address.sol | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 4c3cd8c0fc69..97c4a0cda0c3 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -4056,7 +4056,9 @@ std::string YulUtilFunctions::validatorFunction(Type const& _type, bool _revertO case Type::Category::Address: case Type::Category::Contract: { - templ("condition", "eq(value, " + cleanupFunction(IntegerType(168)) + "(value))"); + // Accept the canonical 20-byte form and TRON's 0x41-prefixed 21-byte form. + // Comparing all high bits at once also rejects values wider than 168 bits. + templ("condition", "or(iszero(div(value, 0x10000000000000000000000000000000000000000)), eq(div(value, 0x10000000000000000000000000000000000000000), 0x41))"); break; } case Type::Category::Integer: diff --git a/test/libsolidity/semanticTests/abiEncoderV2/cleanup/address.sol b/test/libsolidity/semanticTests/abiEncoderV2/cleanup/address.sol index 44a462d1319b..48ad515e2184 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/cleanup/address.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/cleanup/address.sol @@ -21,6 +21,10 @@ contract C { // g(address): 0xabcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff // f(uint256): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff // g(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff +// f(uint256): 0x41abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff +// g(address): 0x41abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff +// f(uint256): 0x42abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff +// g(address): 0x42abcdef0123456789abcdef0123456789abcdefff -> FAILURE // f(uint256): 0x010000000000000000000000000000000000000000 -> 0 // g(address): 0x010000000000000000000000000000000000000000 -> FAILURE // f(uint256): 0x01abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff From 906913fb850fbf02ae4bd9843cf067d4705c8198 Mon Sep 17 00:00:00 2001 From: Asuka Date: Tue, 28 Jul 2026 11:17:19 +0800 Subject: [PATCH 5/7] fix(smt): havoc TRON state effects conservatively --- libsolidity/formal/SMTEncoder.cpp | 62 +++++++++++++++++-- .../tron/state_mutation_havocs_balance.sol | 13 ++++ 2 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 test/libsolidity/smtCheckerTests/tron/state_mutation_havocs_balance.sol diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index 95268032af0e..ad4120839a92 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -726,16 +726,66 @@ void SMTEncoder::endVisit(FunctionCall const& _funCall) " with the CHC engine." ); break; + case FunctionType::Kind::TransferToken: + case FunctionType::Kind::Freeze: + case FunctionType::Kind::Unfreeze: + case FunctionType::Kind::Vote: + case FunctionType::Kind::WithdrawReward: + case FunctionType::Kind::FreezeBalanceV2: + case FunctionType::Kind::UnfreezeBalanceV2: + case FunctionType::Kind::CancelAllUnfreezeV2: + case FunctionType::Kind::WithdrawExpireUnfreeze: + case FunctionType::Kind::DelegateResource: + case FunctionType::Kind::UnDelegateResource: + // These operations mutate TRON account or resource state. Since that state is + // not modeled explicitly, conservatively invalidate the symbolic blockchain + // state so balances and other observable state cannot remain falsely stable. + state().newState(); + m_unsupportedErrors.warning( + 4588_error, + _funCall.location(), + "Assertion checker does not yet implement this type of function call. Its state effects are modeled conservatively." + ); + break; + case FunctionType::Kind::TokenBalance: + case FunctionType::Kind::FreezeExpireTime: + case FunctionType::Kind::ValidateMultiSign: + case FunctionType::Kind::BatchValidateSign: + case FunctionType::Kind::VerifyBurnProof: + case FunctionType::Kind::VerifyTransferProof: + case FunctionType::Kind::VerifyMintProof: + case FunctionType::Kind::PedersenHash: + case FunctionType::Kind::RewardBalance: + case FunctionType::Kind::IsSrCandidate: + case FunctionType::Kind::VoteCount: + case FunctionType::Kind::UsedVoteCount: + case FunctionType::Kind::ReceivedVoteCount: + case FunctionType::Kind::TotalVoteCount: + case FunctionType::Kind::GetChainParameter: + case FunctionType::Kind::AvailableUnfreezeV2Size: + case FunctionType::Kind::UnfreezableBalanceV2: + case FunctionType::Kind::ExpireUnfreezeBalanceV2: + case FunctionType::Kind::DelegatableResource: + case FunctionType::Kind::ResourceV2: + case FunctionType::Kind::CheckUnDelegateResource: + case FunctionType::Kind::ResourceUsage: + case FunctionType::Kind::TotalResource: + case FunctionType::Kind::TotalDelegatedResource: + case FunctionType::Kind::TotalAcquiredResource: + // Keep unsupported TRON queries and precompiles unconstrained, while still + // applying the range/shape constraints of their Solidity return types. + if (!funType.returnParameterTypes().empty()) + setSymbolicUnknownValue(*m_context.expression(_funCall), m_context); + m_unsupportedErrors.warning( + 4588_error, + _funCall.location(), + "Assertion checker does not yet implement this type of function call." + ); + break; case FunctionType::Kind::DelegateCall: case FunctionType::Kind::BareCallCode: case FunctionType::Kind::BareDelegateCall: default: - // The TRON-specific builtins (freeze/unfreeze, vote, the various V2 calls, - // validatemultisign/batchvalidatesign, the zk-proof verifiers, pedersenhash, ...) - // are not modeled here: we only emit the warning below. Their state side effects - // are not havoc'd in this branch; soundness for state mutation across unmodeled - // calls is instead handled by the engine-level reset logic (CHC::unknownFunctionCall - // / makeOutsideFunctionCall and BMC's resetStateVariables paths). m_unsupportedErrors.warning( 4588_error, _funCall.location(), diff --git a/test/libsolidity/smtCheckerTests/tron/state_mutation_havocs_balance.sol b/test/libsolidity/smtCheckerTests/tron/state_mutation_havocs_balance.sol new file mode 100644 index 000000000000..e6ef09cdc08a --- /dev/null +++ b/test/libsolidity/smtCheckerTests/tron/state_mutation_havocs_balance.sol @@ -0,0 +1,13 @@ +contract C { + function f(uint256 amount) public { + uint256 balanceBefore = address(this).balance; + payable(address(this)).freeze(amount, 0); + assert(address(this).balance == balanceBefore); + } +} +// ==== +// SMTEngine: all +// SMTIgnoreCex: yes +// ---- +// Warning 4588: (116-156): Assertion checker does not yet implement this type of function call. Its state effects are modeled conservatively. +// Warning 6328: (166-212): CHC: Assertion violation happens here. From c2bf7882c5ff27d3776fd1b90bddff5d48d265a3 Mon Sep 17 00:00:00 2001 From: Asuka Date: Tue, 28 Jul 2026 15:03:23 +0800 Subject: [PATCH 6/7] fix: preserve TRON target compatibility --- liblangutil/EVMVersion.cpp | 18 -------- libsolidity/codegen/YulUtilFunctions.cpp | 4 +- test/CMakeLists.txt | 1 - test/liblangutil/EVMVersion.cpp | 41 ------------------- .../abiEncoderV2/cleanup/address.sol | 4 -- 5 files changed, 1 insertion(+), 67 deletions(-) delete mode 100644 test/liblangutil/EVMVersion.cpp diff --git a/liblangutil/EVMVersion.cpp b/liblangutil/EVMVersion.cpp index dae910af38e7..4fbfe8de41b0 100644 --- a/liblangutil/EVMVersion.cpp +++ b/liblangutil/EVMVersion.cpp @@ -61,24 +61,6 @@ bool EVMVersion::hasOpcode(Instruction _opcode, std::optional _eofVersi case Instruction::TSTORE: case Instruction::TLOAD: return supportsTransientStorage(); - // TRON-specific instructions are not part of the EOF instruction set. - case Instruction::CALLTOKEN: - case Instruction::TOKENBALANCE: - case Instruction::CALLTOKENVALUE: - case Instruction::CALLTOKENID: - case Instruction::ISCONTRACT: - case Instruction::NATIVEFREEZE: - case Instruction::NATIVEUNFREEZE: - case Instruction::NATIVEFREEZEEXPIRETIME: - case Instruction::NATIVEVOTE: - case Instruction::NATIVEWITHDRAWREWARD: - case Instruction::NATIVEFREEZEBALANCEV2: - case Instruction::NATIVEUNFREEZEBALANCEV2: - case Instruction::NATIVECANCELALLUNFREEZEV2: - case Instruction::NATIVEWITHDRAWEXPIREUNFREEZE: - case Instruction::NATIVEDELEGATERESOURCE: - case Instruction::NATIVEUNDELEGATERESOURCE: - return !_eofVersion.has_value(); // Instructions below are deprecated in EOF case Instruction::CALL: case Instruction::CALLCODE: diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 97c4a0cda0c3..4c3cd8c0fc69 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -4056,9 +4056,7 @@ std::string YulUtilFunctions::validatorFunction(Type const& _type, bool _revertO case Type::Category::Address: case Type::Category::Contract: { - // Accept the canonical 20-byte form and TRON's 0x41-prefixed 21-byte form. - // Comparing all high bits at once also rejects values wider than 168 bits. - templ("condition", "or(iszero(div(value, 0x10000000000000000000000000000000000000000)), eq(div(value, 0x10000000000000000000000000000000000000000), 0x41))"); + templ("condition", "eq(value, " + cleanupFunction(IntegerType(168)) + "(value))"); break; } case Type::Category::Integer: diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8af881053fa6..dbbcf3eaec81 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -63,7 +63,6 @@ detect_stray_source_files("${libevmasm_sources}" "libevmasm/") set(liblangutil_sources liblangutil/CharStream.cpp - liblangutil/EVMVersion.cpp liblangutil/Scanner.cpp liblangutil/SourceLocation.cpp ) diff --git a/test/liblangutil/EVMVersion.cpp b/test/liblangutil/EVMVersion.cpp deleted file mode 100644 index 930ed4caaceb..000000000000 --- a/test/liblangutil/EVMVersion.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ -// SPDX-License-Identifier: GPL-3.0 - -#include -#include - -#include - -namespace solidity::langutil::test -{ - -BOOST_AUTO_TEST_SUITE(EVMVersionTest) - -BOOST_AUTO_TEST_CASE(tron_instructions_are_not_available_in_eof) -{ - for (unsigned opcode = 0xd0; opcode <= 0xdf; ++opcode) - { - auto const instruction = static_cast(opcode); - BOOST_TEST(EVMVersion::osaka().hasOpcode(instruction, std::nullopt)); - BOOST_TEST(!EVMVersion::osaka().hasOpcode(instruction, 1)); - } -} - -BOOST_AUTO_TEST_SUITE_END() - -} diff --git a/test/libsolidity/semanticTests/abiEncoderV2/cleanup/address.sol b/test/libsolidity/semanticTests/abiEncoderV2/cleanup/address.sol index 48ad515e2184..44a462d1319b 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/cleanup/address.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/cleanup/address.sol @@ -21,10 +21,6 @@ contract C { // g(address): 0xabcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff // f(uint256): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff // g(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff -// f(uint256): 0x41abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff -// g(address): 0x41abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff -// f(uint256): 0x42abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff -// g(address): 0x42abcdef0123456789abcdef0123456789abcdefff -> FAILURE // f(uint256): 0x010000000000000000000000000000000000000000 -> 0 // g(address): 0x010000000000000000000000000000000000000000 -> FAILURE // f(uint256): 0x01abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff From d18726334c034738899a3ba6a53fa85e7552b8bf Mon Sep 17 00:00:00 2001 From: Asuka Date: Tue, 28 Jul 2026 15:30:14 +0800 Subject: [PATCH 7/7] fix: keep Standard JSON viaIR behavior unchanged --- libsolidity/interface/StandardCompiler.cpp | 15 +-------------- .../input.json | 1 - .../input.json | 1 - .../standard_no_append_cbor/input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 1 - .../input.json | 12 ------------ .../output.json | 16 ---------------- .../standard_viair_requested/input.json | 3 +-- .../standard_yul_cfg_json_export/input.json | 1 - 25 files changed, 2 insertions(+), 65 deletions(-) delete mode 100644 test/cmdlineTests/standard_viair_experimental_warning/input.json delete mode 100644 test/cmdlineTests/standard_viair_experimental_warning/output.json diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index f5f737310c0d..85495a9e37e2 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -430,7 +430,7 @@ std::optional checkAuxiliaryInputKeys(Json const& _input) std::optional checkSettingsKeys(Json const& _input) { - static std::set keys{"debug", "evmVersion", "eofVersion", "experimentalViaIR", "libraries", "metadata", "modelChecker", "optimizer", "outputSelection", "remappings", "stopAfter", "viaIR"}; + static std::set keys{"debug", "evmVersion", "eofVersion", "libraries", "metadata", "modelChecker", "optimizer", "outputSelection", "remappings", "stopAfter", "viaIR"}; return checkKeys(_input, keys, "settings"); } @@ -820,19 +820,6 @@ std::variant StandardCompiler::parseI return formatFatalError(Error::Type::JSONError, "\"settings.viaIR\" must be a Boolean."); ret.viaIR = settings["viaIR"].get(); } - bool experimentalViaIRAcknowledged = false; - if (settings.contains("experimentalViaIR")) - { - if (!settings["experimentalViaIR"].is_boolean()) - return formatFatalError(Error::Type::JSONError, "\"settings.experimentalViaIR\" must be a Boolean."); - experimentalViaIRAcknowledged = settings["experimentalViaIR"].get(); - } - if (ret.viaIR && !experimentalViaIRAcknowledged) - ret.errors.emplace_back(formatError( - Error::Type::Warning, - "general", - "The via-IR pipeline is experimental in the TRON Solidity compiler. Set \"settings.experimentalViaIR\" to true to acknowledge this and suppress this warning." - )); if (settings.contains("evmVersion")) { diff --git a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/input.json b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/input.json index c306a4e01687..6ff7662901e4 100644 --- a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/input.json +++ b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/input.json @@ -14,7 +14,6 @@ "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": true }, "outputSelection": diff --git a/test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/input.json b/test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/input.json index d93f78f4d145..06b89d0e01bf 100644 --- a/test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/input.json +++ b/test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/input.json @@ -7,7 +7,6 @@ "outputSelection": {"*": {"*": ["ir"]}}, "optimizer": {"enabled": true}, "viaIR": true, - "experimentalViaIR": true, "debug": {"debugInfo": []} } } diff --git a/test/cmdlineTests/standard_no_append_cbor/input.json b/test/cmdlineTests/standard_no_append_cbor/input.json index 8fefb3ee0f50..493325506dda 100644 --- a/test/cmdlineTests/standard_no_append_cbor/input.json +++ b/test/cmdlineTests/standard_no_append_cbor/input.json @@ -10,7 +10,6 @@ "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": true }, diff --git a/test/cmdlineTests/standard_no_append_cbor_with_metadata_hash/input.json b/test/cmdlineTests/standard_no_append_cbor_with_metadata_hash/input.json index a1652b5633d9..f12e45bf2fa9 100644 --- a/test/cmdlineTests/standard_no_append_cbor_with_metadata_hash/input.json +++ b/test/cmdlineTests/standard_no_append_cbor_with_metadata_hash/input.json @@ -10,7 +10,6 @@ "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": true }, diff --git a/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json b/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json index aff5263670d6..422a54f90d9f 100644 --- a/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json +++ b/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "debug": { "debugInfo": [ "ethdebug" diff --git a/test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/input.json b/test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/input.json index 8fac23d615d9..8f8edcd29203 100644 --- a/test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/input.json +++ b/test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "debug": { "debugInfo": [ "ethdebug" diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json index 15d1cd6ace39..8ed44ca05de2 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": false }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json index add6ead1e0a0..27c400f9e946 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": false }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/input.json index 9394bea47fc3..ad74649f5d1d 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": true }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/input.json index 9394bea47fc3..ad74649f5d1d 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": true }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json index 9a0d64f088a5..35c8f940e82d 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": false }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json index 028e195d408c..e4681967f7db 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": false }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json index 4df522786b38..6239a7275e4d 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": false }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json index 1929a6a97ccd..fdb6c95b813e 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": false }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json index 279c7ef44848..5bc9d5467345 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "outputSelection": { "*": { "*": [ diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json index e87a97e5bb08..8952a241f6e7 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "outputSelection": { "*": { "*": [ diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/input.json index 641dcfb1827e..a684e0dc073b 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": true }, diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/input.json index c743d1609f2c..1f09e3a70253 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/input.json @@ -10,7 +10,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "optimizer": { "enabled": true }, diff --git a/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json b/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json index d2490aef88f6..dc86ac68494e 100644 --- a/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json +++ b/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json @@ -5,7 +5,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "outputSelection": { "*": {"*": ["evm.bytecode"]} } diff --git a/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/input.json b/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/input.json index d2490aef88f6..dc86ac68494e 100644 --- a/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/input.json +++ b/test/cmdlineTests/standard_via_ir_intersecting_recursive_cycles_stack_too_deep/input.json @@ -5,7 +5,6 @@ }, "settings": { "viaIR": true, - "experimentalViaIR": true, "outputSelection": { "*": {"*": ["evm.bytecode"]} } diff --git a/test/cmdlineTests/standard_viair_experimental_warning/input.json b/test/cmdlineTests/standard_viair_experimental_warning/input.json deleted file mode 100644 index 0b05d0d0e7cd..000000000000 --- a/test/cmdlineTests/standard_viair_experimental_warning/input.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "A.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.0; contract A {}" - } - }, - "settings": { - "viaIR": true, - "outputSelection": {} - } -} diff --git a/test/cmdlineTests/standard_viair_experimental_warning/output.json b/test/cmdlineTests/standard_viair_experimental_warning/output.json deleted file mode 100644 index c74bd9d6b3a5..000000000000 --- a/test/cmdlineTests/standard_viair_experimental_warning/output.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "errors": [ - { - "component": "general", - "formattedMessage": "The via-IR pipeline is experimental in the TRON Solidity compiler. Set \"settings.experimentalViaIR\" to true to acknowledge this and suppress this warning.", - "message": "The via-IR pipeline is experimental in the TRON Solidity compiler. Set \"settings.experimentalViaIR\" to true to acknowledge this and suppress this warning.", - "severity": "warning", - "type": "Warning" - } - ], - "sources": { - "A.sol": { - "id": 0 - } - } -} diff --git a/test/cmdlineTests/standard_viair_requested/input.json b/test/cmdlineTests/standard_viair_requested/input.json index 542b0372d6b0..76ae807a615c 100644 --- a/test/cmdlineTests/standard_viair_requested/input.json +++ b/test/cmdlineTests/standard_viair_requested/input.json @@ -16,7 +16,6 @@ { "*": { "*": ["ir", "evm.bytecode.object", "evm.bytecode.generatedSources", "evm.deployedBytecode.object"] } }, - "viaIR": true, - "experimentalViaIR": true + "viaIR": true } } diff --git a/test/cmdlineTests/standard_yul_cfg_json_export/input.json b/test/cmdlineTests/standard_yul_cfg_json_export/input.json index 545bf50ae705..b5353721ee09 100644 --- a/test/cmdlineTests/standard_yul_cfg_json_export/input.json +++ b/test/cmdlineTests/standard_yul_cfg_json_export/input.json @@ -8,7 +8,6 @@ "enabled": true }, "viaIR": true, - "experimentalViaIR": true, "outputSelection": {"*": {"*": ["yulCFGJson"]}} } }