mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #14107 from ethereum/push0
Introduce `Shanghai` version and `push0` support
This commit is contained in:
commit
82bde40717
@ -31,7 +31,7 @@ REPODIR="$(realpath "$(dirname "$0")"/..)"
|
||||
# shellcheck source=scripts/common.sh
|
||||
source "${REPODIR}/scripts/common.sh"
|
||||
|
||||
EVM_VALUES=(homestead byzantium constantinople petersburg istanbul berlin london paris)
|
||||
EVM_VALUES=(homestead byzantium constantinople petersburg istanbul berlin london paris shanghai)
|
||||
DEFAULT_EVM=paris
|
||||
[[ " ${EVM_VALUES[*]} " =~ $DEFAULT_EVM ]]
|
||||
OPTIMIZE_VALUES=(0 1)
|
||||
|
@ -4,6 +4,8 @@ Language Features:
|
||||
|
||||
|
||||
Compiler Features:
|
||||
* Assembler: Use ``push0`` for placing ``0`` in the stack for EVM versions starting from "Shanghai". This decreases the deployment costs.
|
||||
* EVM: Support for the EVM Version "Shanghai".
|
||||
* NatSpec: Add support for NatSpec documentation in ``enum`` definitions.
|
||||
* Optimizer: Re-implement simplified version of UnusedAssignEliminator and UnusedStoreEliminator. It can correctly remove some unused assignments in deeply nested loops that were ignored by the old version.
|
||||
* SMTChecker: Properties that are proved safe are now reported explicitly at the end of the analysis. By default, only the number of safe properties is shown. The CLI option ``--model-checker-show-proved-safe`` and the JSON option ``settings.modelChecker.showProvedSafe`` can be enabled to show the full list of safe properties.
|
||||
|
@ -174,6 +174,8 @@ at each version. Backward compatibility is not guaranteed between each version.
|
||||
- The block's base fee (`EIP-3198 <https://eips.ethereum.org/EIPS/eip-3198>`_ and `EIP-1559 <https://eips.ethereum.org/EIPS/eip-1559>`_) can be accessed via the global ``block.basefee`` or ``basefee()`` in inline assembly.
|
||||
- ``paris`` (**default**)
|
||||
- Introduces ``prevrandao()`` and ``block.prevrandao``, and changes the semantics of the now deprecated ``block.difficulty``, disallowing ``difficulty()`` in inline assembly (see `EIP-4399 <https://eips.ethereum.org/EIPS/eip-4399>`_).
|
||||
- ``shanghai``
|
||||
- Cheaper deployment cost due to the introduction of ``push0`` (see `EIP-3855 <https://eips.ethereum.org/EIPS/eip-3855>`_).
|
||||
|
||||
.. index:: ! standard JSON, ! --standard-json
|
||||
.. _compiler-api:
|
||||
|
@ -560,11 +560,18 @@ LinkerObject const& Assembly::assemble() const
|
||||
break;
|
||||
case Push:
|
||||
{
|
||||
unsigned b = max<unsigned>(1, numberEncodingSize(i.data()));
|
||||
unsigned b = numberEncodingSize(i.data());
|
||||
if (b == 0 && !m_evmVersion.hasPush0())
|
||||
{
|
||||
b = 1;
|
||||
}
|
||||
ret.bytecode.push_back(static_cast<uint8_t>(pushInstruction(b)));
|
||||
ret.bytecode.resize(ret.bytecode.size() + b);
|
||||
bytesRef byr(&ret.bytecode.back() + 1 - b, b);
|
||||
toBigEndian(i.data(), byr);
|
||||
if (b > 0)
|
||||
{
|
||||
ret.bytecode.resize(ret.bytecode.size() + b);
|
||||
bytesRef byr(&ret.bytecode.back() + 1 - b, b);
|
||||
toBigEndian(i.data(), byr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PushTag:
|
||||
|
@ -94,6 +94,7 @@ std::map<std::string, Instruction> const solidity::evmasm::c_instructions =
|
||||
{ "MSIZE", Instruction::MSIZE },
|
||||
{ "GAS", Instruction::GAS },
|
||||
{ "JUMPDEST", Instruction::JUMPDEST },
|
||||
{ "PUSH0", Instruction::PUSH0 },
|
||||
{ "PUSH1", Instruction::PUSH1 },
|
||||
{ "PUSH2", Instruction::PUSH2 },
|
||||
{ "PUSH3", Instruction::PUSH3 },
|
||||
@ -242,6 +243,7 @@ static std::map<Instruction, InstructionInfo> const c_instructionInfo =
|
||||
{ Instruction::MSIZE, { "MSIZE", 0, 0, 1, false, Tier::Base } },
|
||||
{ Instruction::GAS, { "GAS", 0, 0, 1, false, Tier::Base } },
|
||||
{ Instruction::JUMPDEST, { "JUMPDEST", 0, 0, 0, true, Tier::Special } },
|
||||
{ Instruction::PUSH0, { "PUSH0", 0, 0, 1, false, Tier::Base } },
|
||||
{ Instruction::PUSH1, { "PUSH1", 1, 0, 1, false, Tier::VeryLow } },
|
||||
{ Instruction::PUSH2, { "PUSH2", 2, 0, 1, false, Tier::VeryLow } },
|
||||
{ Instruction::PUSH3, { "PUSH3", 3, 0, 1, false, Tier::VeryLow } },
|
||||
|
@ -103,6 +103,7 @@ enum class Instruction: uint8_t
|
||||
GAS, ///< get the amount of available gas
|
||||
JUMPDEST, ///< set a potential jump destination
|
||||
|
||||
PUSH0 = 0x5f, ///< place the value 0 on stack
|
||||
PUSH1 = 0x60, ///< place 1 byte item on stack
|
||||
PUSH2, ///< place 2 byte item on stack
|
||||
PUSH3, ///< place 3 byte item on stack
|
||||
@ -207,7 +208,7 @@ constexpr bool isCallInstruction(Instruction _inst) noexcept
|
||||
/// @returns true if the instruction is a PUSH
|
||||
inline bool isPushInstruction(Instruction _inst)
|
||||
{
|
||||
return Instruction::PUSH1 <= _inst && _inst <= Instruction::PUSH32;
|
||||
return Instruction::PUSH0 <= _inst && _inst <= Instruction::PUSH32;
|
||||
}
|
||||
|
||||
/// @returns true if the instruction is a DUP
|
||||
@ -231,7 +232,7 @@ inline bool isLogInstruction(Instruction _inst)
|
||||
/// @returns the number of PUSH Instruction _inst
|
||||
inline unsigned getPushNumber(Instruction _inst)
|
||||
{
|
||||
return static_cast<uint8_t>(_inst) - unsigned(Instruction::PUSH1) + 1;
|
||||
return static_cast<uint8_t>(_inst) - unsigned(Instruction::PUSH0);
|
||||
}
|
||||
|
||||
/// @returns the number of DUP Instruction _inst
|
||||
@ -255,8 +256,8 @@ inline unsigned getLogNumber(Instruction _inst)
|
||||
/// @returns the PUSH<_number> instruction
|
||||
inline Instruction pushInstruction(unsigned _number)
|
||||
{
|
||||
assertThrow(1 <= _number && _number <= 32, InvalidOpcode, std::string("Invalid PUSH instruction requested (") + std::to_string(_number) + ").");
|
||||
return Instruction(unsigned(Instruction::PUSH1) + _number - 1);
|
||||
assertThrow(_number <= 32, InvalidOpcode, std::string("Invalid PUSH instruction requested (") + std::to_string(_number) + ").");
|
||||
return Instruction(unsigned(Instruction::PUSH0) + _number);
|
||||
}
|
||||
|
||||
/// @returns the DUP<_number> instruction
|
||||
|
@ -58,10 +58,11 @@ public:
|
||||
static EVMVersion berlin() { return {Version::Berlin}; }
|
||||
static EVMVersion london() { return {Version::London}; }
|
||||
static EVMVersion paris() { return {Version::Paris}; }
|
||||
static EVMVersion shanghai() { return {Version::Shanghai}; }
|
||||
|
||||
static std::optional<EVMVersion> fromString(std::string const& _version)
|
||||
{
|
||||
for (auto const& v: {homestead(), tangerineWhistle(), spuriousDragon(), byzantium(), constantinople(), petersburg(), istanbul(), berlin(), london(), paris()})
|
||||
for (auto const& v: {homestead(), tangerineWhistle(), spuriousDragon(), byzantium(), constantinople(), petersburg(), istanbul(), berlin(), london(), paris(), shanghai()})
|
||||
if (_version == v.name())
|
||||
return v;
|
||||
return std::nullopt;
|
||||
@ -84,6 +85,7 @@ public:
|
||||
case Version::Berlin: return "berlin";
|
||||
case Version::London: return "london";
|
||||
case Version::Paris: return "paris";
|
||||
case Version::Shanghai: return "shanghai";
|
||||
}
|
||||
return "INVALID";
|
||||
}
|
||||
@ -98,6 +100,7 @@ public:
|
||||
bool hasSelfBalance() const { return *this >= istanbul(); }
|
||||
bool hasBaseFee() const { return *this >= london(); }
|
||||
bool hasPrevRandao() const { return *this >= paris(); }
|
||||
bool hasPush0() const { return *this >= shanghai(); }
|
||||
|
||||
bool hasOpcode(evmasm::Instruction _opcode) const;
|
||||
|
||||
@ -106,7 +109,7 @@ public:
|
||||
bool canOverchargeGasForCall() const { return *this >= tangerineWhistle(); }
|
||||
|
||||
private:
|
||||
enum class Version { Homestead, TangerineWhistle, SpuriousDragon, Byzantium, Constantinople, Petersburg, Istanbul, Berlin, London, Paris };
|
||||
enum class Version { Homestead, TangerineWhistle, SpuriousDragon, Byzantium, Constantinople, Petersburg, Istanbul, Berlin, London, Paris, Shanghai };
|
||||
|
||||
EVMVersion(Version _version): m_version(_version) {}
|
||||
|
||||
|
@ -105,7 +105,7 @@ EVM_VERSIONS="homestead byzantium"
|
||||
|
||||
if [ -z "$CI" ]
|
||||
then
|
||||
EVM_VERSIONS+=" constantinople petersburg istanbul berlin london paris"
|
||||
EVM_VERSIONS+=" constantinople petersburg istanbul berlin london paris shanghai"
|
||||
fi
|
||||
|
||||
# And then run the Solidity unit-tests in the matrix combination of optimizer / no optimizer
|
||||
|
@ -593,7 +593,7 @@ General Information)").c_str(),
|
||||
g_strEVMVersion.c_str(),
|
||||
po::value<string>()->value_name("version")->default_value(EVMVersion{}.name()),
|
||||
"Select desired EVM version. Either homestead, tangerineWhistle, spuriousDragon, "
|
||||
"byzantium, constantinople, petersburg, istanbul, berlin, london or paris."
|
||||
"byzantium, constantinople, petersburg, istanbul, berlin, london, paris or shanghai."
|
||||
)
|
||||
;
|
||||
if (!_forHelp) // Note: We intentionally keep this undocumented for now.
|
||||
|
@ -124,6 +124,8 @@ EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm):
|
||||
m_evmRevision = EVMC_LONDON;
|
||||
else if (_evmVersion == langutil::EVMVersion::paris())
|
||||
m_evmRevision = EVMC_PARIS;
|
||||
else if (_evmVersion == langutil::EVMVersion::shanghai())
|
||||
m_evmRevision = EVMC_SHANGHAI;
|
||||
else
|
||||
assertThrow(false, Exception, "Unsupported EVM version");
|
||||
|
||||
|
@ -330,12 +330,16 @@ BOOST_AUTO_TEST_CASE(immutable)
|
||||
|
||||
checkCompilation(_assembly);
|
||||
|
||||
string genericPush0 = evmVersion.hasPush0() ? "5f" : "6000";
|
||||
// PUSH1 0x1b v/s PUSH1 0x19
|
||||
string dataOffset = evmVersion.hasPush0() ? "6019" : "601b" ;
|
||||
|
||||
BOOST_CHECK_EQUAL(
|
||||
_assembly.assemble().toHex(),
|
||||
// root.asm
|
||||
// assign "someImmutable"
|
||||
"602a" // PUSH1 42 - value for someImmutable
|
||||
"6000" // PUSH1 0 - offset of code into which to insert the immutable
|
||||
"602a" + // PUSH1 42 - value for someImmutable
|
||||
genericPush0 + // PUSH1 0 - offset of code into which to insert the immutable
|
||||
"8181" // DUP2 DUP2
|
||||
"6001" // PUSH1 1 - offset of first someImmutable in sub_0
|
||||
"01" // ADD - add offset of immutable to offset of code
|
||||
@ -344,13 +348,13 @@ BOOST_AUTO_TEST_CASE(immutable)
|
||||
"01" // ADD - add offset of immutable to offset of code
|
||||
"52" // MSTORE
|
||||
// assign "someOtherImmutable"
|
||||
"6017" // PUSH1 23 - value for someOtherImmutable
|
||||
"6000" // PUSH1 0 - offset of code into which to insert the immutable
|
||||
"6017" + // PUSH1 23 - value for someOtherImmutable
|
||||
genericPush0 + // PUSH1 0 - offset of code into which to insert the immutable
|
||||
"6022" // PUSH1 34 - offset of someOtherImmutable in sub_0
|
||||
"01" // ADD - add offset of immutable to offset of code
|
||||
"52" // MSTORE
|
||||
"6063" // PUSH1 0x63 - dataSize(sub_0)
|
||||
"601b" // PUSH1 0x23 - dataOffset(sub_0)
|
||||
"6063" + // PUSH1 0x63 - dataSize(sub_0)
|
||||
dataOffset + // PUSH1 0x23 - dataOffset(sub_0)
|
||||
"fe" // INVALID
|
||||
// end of root.asm
|
||||
// sub.asm
|
||||
|
@ -112,15 +112,21 @@ BOOST_AUTO_TEST_CASE(string_storage)
|
||||
// Costs with 0 are cases which cannot be triggered in tests.
|
||||
if (evmVersion < EVMVersion::istanbul())
|
||||
CHECK_DEPLOY_GAS(0, 109241, evmVersion);
|
||||
else
|
||||
else if (evmVersion < EVMVersion::shanghai())
|
||||
CHECK_DEPLOY_GAS(0, 97697, evmVersion);
|
||||
// Shanghai is cheaper due to `push0`
|
||||
else
|
||||
CHECK_DEPLOY_GAS(0, 97071, evmVersion);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (evmVersion < EVMVersion::istanbul())
|
||||
CHECK_DEPLOY_GAS(139013, 123969, evmVersion);
|
||||
else
|
||||
else if (evmVersion < EVMVersion::shanghai())
|
||||
CHECK_DEPLOY_GAS(123361, 110969, evmVersion);
|
||||
// Shanghai is cheaper due to `push0`
|
||||
else
|
||||
CHECK_DEPLOY_GAS(121493, 110969, evmVersion);
|
||||
}
|
||||
}
|
||||
else if (evmVersion < EVMVersion::istanbul())
|
||||
@ -198,7 +204,11 @@ BOOST_AUTO_TEST_CASE(single_callvaluecheck)
|
||||
size_t bytecodeSizeNonpayable = m_compiler.object("Nonpayable").bytecode.size();
|
||||
size_t bytecodeSizePayable = m_compiler.object("Payable").bytecode.size();
|
||||
|
||||
BOOST_CHECK_EQUAL(bytecodeSizePayable - bytecodeSizeNonpayable, 26);
|
||||
auto evmVersion = solidity::test::CommonOptions::get().evmVersion();
|
||||
if (evmVersion < EVMVersion::shanghai())
|
||||
BOOST_CHECK_EQUAL(bytecodeSizePayable - bytecodeSizeNonpayable, 26);
|
||||
else
|
||||
BOOST_CHECK_EQUAL(bytecodeSizePayable - bytecodeSizeNonpayable, 24);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
@ -47,7 +47,9 @@ BOOST_AUTO_TEST_CASE(does_not_include_creation_time_only_internal_functions)
|
||||
bytes const& runtimeBytecode = solidity::test::bytecodeSansMetadata(compiler().runtimeObject("C").bytecode);
|
||||
BOOST_CHECK(creationBytecode.size() >= 90);
|
||||
BOOST_CHECK(creationBytecode.size() <= 120);
|
||||
BOOST_CHECK(runtimeBytecode.size() >= 10);
|
||||
auto evmVersion = solidity::test::CommonOptions::get().evmVersion();
|
||||
unsigned threshold = evmVersion.hasPush0() ? 9 : 10;
|
||||
BOOST_CHECK(runtimeBytecode.size() >= threshold);
|
||||
BOOST_CHECK(runtimeBytecode.size() <= 30);
|
||||
}
|
||||
|
||||
|
@ -210,7 +210,10 @@ BOOST_AUTO_TEST_CASE(literal_false)
|
||||
)";
|
||||
bytes code = compileFirstExpression(sourceCode);
|
||||
|
||||
bytes expectation({uint8_t(Instruction::PUSH1), 0x0});
|
||||
bytes expectation = solidity::test::CommonOptions::get().evmVersion().hasPush0() ?
|
||||
bytes{uint8_t(Instruction::PUSH0)} :
|
||||
bytes{uint8_t(Instruction::PUSH1), 0x0};
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
|
||||
}
|
||||
|
||||
@ -344,21 +347,27 @@ BOOST_AUTO_TEST_CASE(arithmetic)
|
||||
}
|
||||
)";
|
||||
bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "y"}});
|
||||
|
||||
bool hasPush0 = solidity::test::CommonOptions::get().evmVersion().hasPush0();
|
||||
bytes push0Bytes = hasPush0 ?
|
||||
bytes{uint8_t(Instruction::PUSH0)} :
|
||||
bytes{uint8_t(Instruction::PUSH1), 0x0};
|
||||
uint8_t size = hasPush0 ? 0x65: 0x67;
|
||||
bytes panic =
|
||||
bytes{
|
||||
uint8_t(Instruction::JUMPDEST),
|
||||
uint8_t(Instruction::PUSH32)
|
||||
} +
|
||||
util::fromHex("4E487B7100000000000000000000000000000000000000000000000000000000") +
|
||||
push0Bytes +
|
||||
bytes{
|
||||
uint8_t(Instruction::PUSH1), 0x0,
|
||||
uint8_t(Instruction::MSTORE),
|
||||
uint8_t(Instruction::PUSH1), 0x12,
|
||||
uint8_t(Instruction::PUSH1), 0x4,
|
||||
uint8_t(Instruction::MSTORE),
|
||||
uint8_t(Instruction::PUSH1), 0x24,
|
||||
uint8_t(Instruction::PUSH1), 0x0,
|
||||
uint8_t(Instruction::PUSH1), 0x24
|
||||
} +
|
||||
push0Bytes +
|
||||
bytes{
|
||||
uint8_t(Instruction::REVERT),
|
||||
uint8_t(Instruction::JUMPDEST),
|
||||
uint8_t(Instruction::JUMP),
|
||||
@ -405,7 +414,7 @@ BOOST_AUTO_TEST_CASE(arithmetic)
|
||||
uint8_t(Instruction::DIV),
|
||||
uint8_t(Instruction::PUSH1), 0x1,
|
||||
uint8_t(Instruction::MUL),
|
||||
uint8_t(Instruction::PUSH1), 0x67,
|
||||
uint8_t(Instruction::PUSH1), size,
|
||||
uint8_t(Instruction::JUMP)
|
||||
} + panic;
|
||||
else
|
||||
@ -447,7 +456,7 @@ BOOST_AUTO_TEST_CASE(arithmetic)
|
||||
uint8_t(Instruction::JUMPDEST),
|
||||
uint8_t(Instruction::DIV),
|
||||
uint8_t(Instruction::MUL),
|
||||
uint8_t(Instruction::PUSH1), 0x67,
|
||||
uint8_t(Instruction::PUSH1), size,
|
||||
uint8_t(Instruction::JUMP)
|
||||
} + panic;
|
||||
|
||||
@ -463,11 +472,17 @@ BOOST_AUTO_TEST_CASE(unary_operators)
|
||||
)";
|
||||
bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "y"}});
|
||||
|
||||
bytes push0Bytes = solidity::test::CommonOptions::get().evmVersion().hasPush0() ?
|
||||
bytes{uint8_t(Instruction::PUSH0)} :
|
||||
bytes{uint8_t(Instruction::PUSH1), 0x0};
|
||||
|
||||
bytes expectation;
|
||||
if (solidity::test::CommonOptions::get().optimize)
|
||||
expectation = {
|
||||
expectation = bytes{
|
||||
uint8_t(Instruction::DUP1),
|
||||
uint8_t(Instruction::PUSH1), 0x0,
|
||||
} +
|
||||
push0Bytes +
|
||||
bytes{
|
||||
uint8_t(Instruction::SUB),
|
||||
uint8_t(Instruction::NOT),
|
||||
uint8_t(Instruction::PUSH1), 0x2,
|
||||
@ -475,10 +490,12 @@ BOOST_AUTO_TEST_CASE(unary_operators)
|
||||
uint8_t(Instruction::ISZERO)
|
||||
};
|
||||
else
|
||||
expectation = {
|
||||
expectation = bytes{
|
||||
uint8_t(Instruction::PUSH1), 0x2,
|
||||
uint8_t(Instruction::DUP2),
|
||||
uint8_t(Instruction::PUSH1), 0x0,
|
||||
} +
|
||||
push0Bytes +
|
||||
bytes{
|
||||
uint8_t(Instruction::SUB),
|
||||
uint8_t(Instruction::NOT),
|
||||
uint8_t(Instruction::EQ),
|
||||
|
31
test/libsolidity/semanticTests/shanghai/evmone_support.sol
Normal file
31
test/libsolidity/semanticTests/shanghai/evmone_support.sol
Normal file
@ -0,0 +1,31 @@
|
||||
contract ShortReturn {
|
||||
constructor() {
|
||||
assembly {
|
||||
// return(0, 32)
|
||||
// PUSH1 0x20 PUSH0 RETURN
|
||||
mstore(0, hex"60205ff3")
|
||||
return(0, 4)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface DoesItReturnZero {
|
||||
function foo() external pure returns (uint256);
|
||||
}
|
||||
|
||||
contract Test {
|
||||
ShortReturn immutable shortReturn = new ShortReturn();
|
||||
function bytecode() external view returns(bytes memory) {
|
||||
return address(shortReturn).code;
|
||||
}
|
||||
function isPush0Supported() external view returns (bool) {
|
||||
assert(DoesItReturnZero(address(shortReturn)).foo() == 0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// EVMVersion: >=shanghai
|
||||
// ----
|
||||
// bytecode() -> 0x20, 4, 0x60205ff300000000000000000000000000000000000000000000000000000000
|
||||
// isPush0Supported() -> true
|
11
test/libsolidity/semanticTests/shanghai/push0.sol
Normal file
11
test/libsolidity/semanticTests/shanghai/push0.sol
Normal file
@ -0,0 +1,11 @@
|
||||
contract C {
|
||||
function zero() external returns (uint) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// EVMVersion: >=shanghai
|
||||
// ----
|
||||
// zero() -> 0
|
@ -7,6 +7,6 @@ contract test {
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >byzantium
|
||||
// EVMVersion: >=shanghai
|
||||
// ----
|
||||
// Warning 5574: (21-27154): Contract code size is 27192 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries.
|
||||
// Warning 5574: (21-27154): Contract code size is 27186 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries.
|
||||
|
@ -7,6 +7,6 @@ contract test {
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >byzantium
|
||||
// EVMVersion: >=shanghai
|
||||
// ----
|
||||
// Warning 5574: (21-27154): Contract code size is 27209 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries.
|
||||
// Warning 5574: (21-27154): Contract code size is 27205 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries.
|
||||
|
@ -0,0 +1,19 @@
|
||||
// Ok
|
||||
contract push0 {}
|
||||
|
||||
contract A {
|
||||
// Ok, warning about shadowing
|
||||
function push0() external {}
|
||||
}
|
||||
|
||||
contract C {
|
||||
function f() external {
|
||||
assembly {
|
||||
// Not okay
|
||||
push0()
|
||||
}
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 2519: (77-105): This declaration shadows an existing declaration.
|
||||
// DeclarationError 4619: (205-210): Function "push0" not found.
|
6
test/libyul/yulSyntaxTests/invalid/push0_disallowed.yul
Normal file
6
test/libyul/yulSyntaxTests/invalid/push0_disallowed.yul
Normal file
@ -0,0 +1,6 @@
|
||||
// Based on ./push_disallowed.yul (which already includes push0).
|
||||
{
|
||||
push0()
|
||||
}
|
||||
// ----
|
||||
// DeclarationError 4619: (72-77): Function "push0" not found.
|
@ -381,6 +381,7 @@ u256 EVMInstructionInterpreter::eval(
|
||||
case Instruction::JUMP:
|
||||
case Instruction::JUMPI:
|
||||
case Instruction::JUMPDEST:
|
||||
case Instruction::PUSH0:
|
||||
case Instruction::PUSH1:
|
||||
case Instruction::PUSH2:
|
||||
case Instruction::PUSH3:
|
||||
|
Loading…
Reference in New Issue
Block a user