diff --git a/liblangutil/EVMVersion.cpp b/liblangutil/EVMVersion.cpp index c953eda0f8e0..7b34fe7d2ed4 100644 --- a/liblangutil/EVMVersion.cpp +++ b/liblangutil/EVMVersion.cpp @@ -46,8 +46,9 @@ bool EVMVersion::hasOpcode(Instruction _opcode) const return hasChainID(); case Instruction::SELFBALANCE: return hasSelfBalance(); + case Instruction::BASEFEE: + return hasBaseFee(); default: return true; } } - diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index f4176c1b2418..86202e378828 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -112,14 +112,22 @@ pair createFunction( return {name, f}; } -set createReservedIdentifiers() +set createReservedIdentifiers(langutil::EVMVersion _evmVersion) { + // TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the name + // basefee for VMs before london. + auto baseFeeException = [&](evmasm::Instruction _instr) -> bool + { + return _instr == evmasm::Instruction::BASEFEE && _evmVersion < langutil::EVMVersion::london(); + }; + set reserved; for (auto const& instr: evmasm::c_instructions) { string name = instr.first; transform(name.begin(), name.end(), name.begin(), [](unsigned char _c) { return tolower(_c); }); - reserved.emplace(name); + if (!baseFeeException(instr.second)) + reserved.emplace(name); } reserved += vector{ "linkersymbol"_yulstring, @@ -300,7 +308,7 @@ EVMDialect::EVMDialect(langutil::EVMVersion _evmVersion, bool _objectAccess): m_objectAccess(_objectAccess), m_evmVersion(_evmVersion), m_functions(createBuiltins(_evmVersion, _objectAccess)), - m_reserved(createReservedIdentifiers()) + m_reserved(createReservedIdentifiers(_evmVersion)) { } diff --git a/scripts/error_codes.py b/scripts/error_codes.py index 18179b4bc604..320074ff1876 100755 --- a/scripts/error_codes.py +++ b/scripts/error_codes.py @@ -198,7 +198,8 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False): # The warning may or may not exist in a compiler build. "4591", # "There are more than 256 warnings. Ignoring the rest." # Due to 3805, the warning lists look different for different compiler builds. - "1834" # Unimplemented feature error, as we do not test it anymore via cmdLineTests + "1834", # Unimplemented feature error, as we do not test it anymore via cmdLineTests + "5430" # basefee being used in inline assembly for EVMVersion < london } assert len(test_ids & white_ids) == 0, "The sets are not supposed to intersect" test_ids |= white_ids diff --git a/scripts/test_antlr_grammar.sh b/scripts/test_antlr_grammar.sh index 51e0df0cbaed..333cea0df9b6 100755 --- a/scripts/test_antlr_grammar.sh +++ b/scripts/test_antlr_grammar.sh @@ -118,7 +118,9 @@ done < <( grep -v -E 'literals/.*_direction_override.*.sol' | # Skipping a test with "revert E;" because ANTLR cannot distinguish it from # a variable declaration. - grep -v -E 'revertStatement/non_called.sol' + grep -v -E 'revertStatement/non_called.sol' | + # Skipping a test with "let basefee := ..." + grep -v -E 'inlineAssembly/basefee_berlin_function.sol' ) YUL_FILES=() diff --git a/test/libsolidity/semanticTests/inlineAssembly/basefee_berlin_function.sol b/test/libsolidity/semanticTests/inlineAssembly/basefee_berlin_function.sol new file mode 100644 index 000000000000..81c1ee43163a --- /dev/null +++ b/test/libsolidity/semanticTests/inlineAssembly/basefee_berlin_function.sol @@ -0,0 +1,22 @@ +contract C { + function f() public view returns (uint ret) { + assembly { + let basefee := sload(0) + ret := basefee + } + } + function g() public pure returns (uint ret) { + assembly { + function basefee() -> r { + r := 1000 + } + ret := basefee() + } + } +} +// ==== +// compileViaYul: also +// EVMVersion: <=berlin +// ---- +// f() -> 0 +// g() -> 1000 diff --git a/test/libsolidity/syntaxTests/inlineAssembly/basefee_reserved_london.sol b/test/libsolidity/syntaxTests/inlineAssembly/basefee_reserved_london.sol new file mode 100644 index 000000000000..00ecaf01a426 --- /dev/null +++ b/test/libsolidity/syntaxTests/inlineAssembly/basefee_reserved_london.sol @@ -0,0 +1,12 @@ +contract C { + function f() public view returns (uint ret) { + assembly { + let basefee := sload(0) + ret := basefee + } + } +} +// ==== +// EVMVersion: =london +// ---- +// ParserError 5568: (98-105): Cannot use builtin function name "basefee" as identifier name. diff --git a/test/libsolidity/syntaxTests/types/magic_block_basefee_error.sol b/test/libsolidity/syntaxTests/types/magic_block_basefee_error.sol index 706fa3183a32..b723d0aeeb2b 100644 --- a/test/libsolidity/syntaxTests/types/magic_block_basefee_error.sol +++ b/test/libsolidity/syntaxTests/types/magic_block_basefee_error.sol @@ -2,14 +2,8 @@ contract C { function f() public view returns (uint) { return block.basefee; } - function g() public view returns (uint ret) { - assembly { - ret := basefee() - } - } } // ==== -// EVMVersion: =berlin +// EVMVersion: <=berlin // ---- // TypeError 5921: (74-87): "basefee" is not supported by the VM version. -// TypeError 5430: (183-190): The "basefee" instruction is only available for London-compatible VMs (you are currently compiling for "berlin").