From 7f1a2be0fee99531b5e9c0eca7dc1c70b9ffcaa0 Mon Sep 17 00:00:00 2001
From: hrkrshnn <webmail.hari@gmail.com>
Date: Mon, 9 Aug 2021 12:40:14 +0200
Subject: [PATCH 1/2] Allow basefee as Yul identifier for EVMVersion < london

This was done to prevent basefee from being a breaking change. This change will be removed in 0.9.0.

TODO revert this commit in breaking.
---
 libyul/backends/evm/EVMDialect.cpp                 | 14 +++++++++++---
 scripts/error_codes.py                             |  3 ++-
 .../types/magic_block_basefee_error.sol            |  8 +-------
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp
index f4176c1b2..86202e378 100644
--- a/libyul/backends/evm/EVMDialect.cpp
+++ b/libyul/backends/evm/EVMDialect.cpp
@@ -112,14 +112,22 @@ pair<YulString, BuiltinFunctionForEVM> createFunction(
 	return {name, f};
 }
 
-set<YulString> createReservedIdentifiers()
+set<YulString> 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<YulString> 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<YulString>{
 		"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 18179b4bc..320074ff1 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/test/libsolidity/syntaxTests/types/magic_block_basefee_error.sol b/test/libsolidity/syntaxTests/types/magic_block_basefee_error.sol
index 706fa3183..b723d0aee 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").

From 892700d769ad23fd7cd252cd6f77044032cc27d5 Mon Sep 17 00:00:00 2001
From: hrkrshnn <webmail.hari@gmail.com>
Date: Mon, 9 Aug 2021 12:45:28 +0200
Subject: [PATCH 2/2] Tests for basefee as identifier in inline assembly

Also added basefee to `EVMVersion::hasOpcode(...)`
---
 liblangutil/EVMVersion.cpp                    |  3 ++-
 scripts/test_antlr_grammar.sh                 |  4 +++-
 .../basefee_berlin_function.sol               | 22 +++++++++++++++++++
 .../basefee_reserved_london.sol               | 12 ++++++++++
 4 files changed, 39 insertions(+), 2 deletions(-)
 create mode 100644 test/libsolidity/semanticTests/inlineAssembly/basefee_berlin_function.sol
 create mode 100644 test/libsolidity/syntaxTests/inlineAssembly/basefee_reserved_london.sol

diff --git a/liblangutil/EVMVersion.cpp b/liblangutil/EVMVersion.cpp
index c953eda0f..7b34fe7d2 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/scripts/test_antlr_grammar.sh b/scripts/test_antlr_grammar.sh
index 51e0df0cb..333cea0df 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 000000000..81c1ee431
--- /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 000000000..00ecaf01a
--- /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.