Merge pull request #6089 from ethereum/extcodehash

Consider extcodehash as part of Constantinople
This commit is contained in:
chriseth 2019-02-26 17:04:01 +01:00 committed by GitHub
commit 4e74c508ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 31 deletions

View File

@ -5,6 +5,7 @@ Language Features:
Compiler Features: Compiler Features:
* Inline Assembly: Consider ``extcodehash`` as part of Constantinople.
* SMTChecker: Do not report underflow/overflow if they always revert. This removes false positives when using ``SafeMath``. * SMTChecker: Do not report underflow/overflow if they always revert. This removes false positives when using ``SafeMath``.
* Static Analyzer: Warn about expressions with custom types when they have no effect. * Static Analyzer: Warn about expressions with custom types when they have no effect.
* Optimizer: Add rule for shifts with constants for Constantinople. * Optimizer: Add rule for shifts with constants for Constantinople.

View File

@ -74,6 +74,7 @@ public:
bool hasStaticCall() const { return *this >= byzantium(); } bool hasStaticCall() const { return *this >= byzantium(); }
bool hasBitwiseShifting() const { return *this >= constantinople(); } bool hasBitwiseShifting() const { return *this >= constantinople(); }
bool hasCreate2() const { return *this >= constantinople(); } bool hasCreate2() const { return *this >= constantinople(); }
bool hasExtCodeHash() const { return *this >= constantinople(); }
/// Whether we have to retain the costs for the call opcode itself (false), /// Whether we have to retain the costs for the call opcode itself (false),
/// or whether we can just forward easily all remaining gas (true). /// or whether we can just forward easily all remaining gas (true).

View File

@ -641,45 +641,47 @@ void AsmAnalyzer::warnOnInstructions(solidity::Instruction _instr, SourceLocatio
solAssert(m_evmVersion.hasBitwiseShifting() == m_evmVersion.hasCreate2(), ""); solAssert(m_evmVersion.hasBitwiseShifting() == m_evmVersion.hasCreate2(), "");
solAssert(m_dialect->flavour != AsmFlavour::Yul, ""); solAssert(m_dialect->flavour != AsmFlavour::Yul, "");
if (_instr == solidity::Instruction::EXTCODEHASH) auto warningForVM = [=](string const& vmKindMessage) {
m_errorReporter.warning( m_errorReporter.warning(
_location, _location,
"The \"" + "The \"" +
boost::to_lower_copy(instructionInfo(_instr).name) boost::to_lower_copy(instructionInfo(_instr).name)
+ "\" instruction is not supported by the VM version \"" + + "\" instruction is " +
"" + m_evmVersion.name() + vmKindMessage +
"\" you are currently compiling for. " + " VMs. " +
"It will be interpreted as an invalid instruction on this VM."
);
else if ((
_instr == solidity::Instruction::RETURNDATACOPY ||
_instr == solidity::Instruction::RETURNDATASIZE ||
_instr == solidity::Instruction::STATICCALL
) && !m_evmVersion.supportsReturndata())
m_errorReporter.warning(
_location,
"The \"" +
boost::to_lower_copy(instructionInfo(_instr).name)
+ "\" instruction is only available for Byzantium-compatible VMs. " +
"You are currently compiling for \"" + "You are currently compiling for \"" +
m_evmVersion.name() + m_evmVersion.name() +
"\", where it will be interpreted as an invalid instruction." "\", where it will be interpreted as an invalid instruction."
); );
};
if ((
_instr == solidity::Instruction::RETURNDATACOPY ||
_instr == solidity::Instruction::RETURNDATASIZE
) && !m_evmVersion.supportsReturndata())
{
warningForVM("only available for Byzantium-compatible");
}
else if (_instr == solidity::Instruction::STATICCALL && !m_evmVersion.hasStaticCall())
{
warningForVM("only available for Byzantium-compatible");
}
else if (( else if ((
_instr == solidity::Instruction::SHL || _instr == solidity::Instruction::SHL ||
_instr == solidity::Instruction::SHR || _instr == solidity::Instruction::SHR ||
_instr == solidity::Instruction::SAR || _instr == solidity::Instruction::SAR
_instr == solidity::Instruction::CREATE2
) && !m_evmVersion.hasBitwiseShifting()) ) && !m_evmVersion.hasBitwiseShifting())
m_errorReporter.warning( {
_location, warningForVM("only available for Constantinople-compatible");
"The \"" + }
boost::to_lower_copy(instructionInfo(_instr).name) else if (_instr == solidity::Instruction::CREATE2 && !m_evmVersion.hasCreate2())
+ "\" instruction is only available for Constantinople-compatible VMs. " + {
"You are currently compiling for \"" + warningForVM("only available for Constantinople-compatible");
m_evmVersion.name() + }
"\", where it will be interpreted as an invalid instruction." else if (_instr == solidity::Instruction::EXTCODEHASH && !m_evmVersion.hasExtCodeHash())
); {
warningForVM("only available for Constantinople-compatible");
}
else if (_instr == solidity::Instruction::JUMP || _instr == solidity::Instruction::JUMPI || _instr == solidity::Instruction::JUMPDEST) else if (_instr == solidity::Instruction::JUMP || _instr == solidity::Instruction::JUMPI || _instr == solidity::Instruction::JUMPDEST)
{ {
if (m_dialect->flavour == AsmFlavour::Loose) if (m_dialect->flavour == AsmFlavour::Loose)

View File

@ -417,10 +417,12 @@ BOOST_AUTO_TEST_CASE(extcodehash_as_variable)
)"; )";
// This needs special treatment, because the message mentions the EVM version, // This needs special treatment, because the message mentions the EVM version,
// so cannot be run via isoltest. // so cannot be run via isoltest.
CHECK_ALLOW_MULTI(text, (std::vector<std::pair<Error::Type, std::string>>{ vector<pair<Error::Type, std::string>> expectations(vector<pair<Error::Type, std::string>>{
{Error::Type::Warning, "Variable is shadowed in inline assembly by an instruction of the same name"}, {Error::Type::Warning, "Variable is shadowed in inline assembly by an instruction of the same name"}
{Error::Type::Warning, "The \"extcodehash\" instruction is not supported by the VM version"}, });
})); if (!dev::test::Options::get().evmVersion().hasExtCodeHash())
expectations.emplace_back(make_pair(Error::Type::Warning, std::string("\"extcodehash\" instruction is only available for Constantinople-compatible VMs.")));
CHECK_ALLOW_MULTI(text, expectations);
} }
BOOST_AUTO_TEST_CASE(getter_is_memory_type) BOOST_AUTO_TEST_CASE(getter_is_memory_type)