Mark EVM instruction pc() as deprecated when used in inline assembly.

This commit is contained in:
Christian Parpart 2020-05-12 17:09:25 +02:00
parent b488627c79
commit b7fa5d5040
11 changed files with 74 additions and 31 deletions

View File

@ -2,6 +2,7 @@
Language Features:
* Permit calldata location for all variables.
* Yul: EVM instruction `pc()` is marked deprecated and will be removed in the next breaking release.
Compiler Features:

View File

@ -273,6 +273,7 @@ bool SyntaxChecker::visit(InlineAssembly const& _inlineAssembly)
"The msize instruction cannot be used when the Yul optimizer is activated because "
"it can change its semantics. Either disable the Yul optimizer or do not use the instruction."
);
return false;
}

View File

@ -73,7 +73,7 @@ AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect(Dialect const& _dialect,
{},
_object.dataNames()
).analyze(*_object.code);
yulAssert(success && errorList.empty(), "Invalid assembly/yul code.");
yulAssert(success && !errors.hasErrors(), "Invalid assembly/yul code.");
return analysisInfo;
}
@ -259,6 +259,8 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
returnTypes = &f->returns;
if (f->literalArguments)
needsLiteralArguments = &f->literalArguments.value();
warnOnInstructions(_funCall);
}
else if (!m_currentScope->lookup(_funCall.functionName.name, GenericVisitor{
[&](Scope::Variable const&)
@ -275,10 +277,11 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
}
}))
{
if (!warnOnInstructions(_funCall.functionName.name.str(), _funCall.functionName.location))
if (!warnOnInstructions(_funCall))
declarationError(_funCall.functionName.location, "Function not found.");
yulAssert(!watcher.ok(), "Expected a reported error.");
}
if (parameterTypes && _funCall.arguments.size() != parameterTypes->size())
typeError(
_funCall.functionName.location,
@ -553,6 +556,14 @@ bool AsmAnalyzer::warnOnInstructions(evmasm::Instruction _instr, SourceLocation
errorForVM("only available for Constantinople-compatible");
else if (_instr == evmasm::Instruction::CHAINID && !m_evmVersion.hasChainID())
errorForVM("only available for Istanbul-compatible");
else if (_instr == evmasm::Instruction::PC)
m_errorReporter.warning(
2450_error,
_location,
"The \"" +
boost::to_lower_copy(instructionInfo(_instr).name) +
"\" instruction is deprecated and will be removed in the next breaking release."
);
else if (_instr == evmasm::Instruction::SELFBALANCE && !m_evmVersion.hasSelfBalance())
errorForVM("only available for Istanbul-compatible");
else if (

View File

@ -112,6 +112,11 @@ private:
bool warnOnInstructions(evmasm::Instruction _instr, langutil::SourceLocation const& _location);
bool warnOnInstructions(std::string const& _instrIdentifier, langutil::SourceLocation const& _location);
bool warnOnInstructions(FunctionCall const& _functionCall)
{
return warnOnInstructions(_functionCall.functionName.name.str(), _functionCall.functionName.location);
}
void typeError(langutil::SourceLocation const& _location, std::string const& _description);
void declarationError(langutil::SourceLocation const& _location, std::string const& _description);

View File

@ -90,7 +90,6 @@ void MSizeFinder::operator()(FunctionCall const& _functionCall)
m_msizeFound = true;
}
map<YulString, SideEffects> SideEffectsPropagator::sideEffects(
Dialect const& _dialect,
CallGraph const& _directCallGraph

View File

@ -0,0 +1,9 @@
contract C {
function f() pure public {
assembly {
pop(pc())
}
}
}
// ----
// Warning: (61-63): The "pc" instruction is deprecated and will be removed in the next breaking release.

View File

@ -1,8 +0,0 @@
{
sstore(0, pc())
}
// ----
// Trace:
// INVALID()
// Memory dump:
// Storage dump:

View File

@ -6,7 +6,6 @@
pop(extcodehash(0))
pop(returndatasize())
pop(sload(0))
pop(pc())
pop(msize())
pop(mload(0))
pop(sload(0))

View File

@ -1,10 +1,23 @@
{
let a
function gcd(_a, _b) -> out
{
// GCD algorithm. in order to test underlying stack compressor this function must not be inlined.
switch _b
case 0 { out := _a }
default { out := gcd(_b, mod(_a, _b)) }
}
function f() -> out
{
out := gcd(10, 15)
}
function foo_singlereturn_0() -> out
{
mstore(lt(or(gt(1,or(or(gt(or(or(or(1,gt(or(gt(or(or(keccak256(pc(),or(gt(not(pc()),1),1)),1),not(1)),pc()),1),pc())),lt(or(1,sub(pc(),1)),1)),pc()),1),1),gt(not(pc()),1))),1),1),1)
sstore(not(pc()),1)
mstore(lt(or(gt(1,or(or(gt(or(or(or(1,gt(or(gt(or(or(keccak256(f(),or(gt(not(f()),1),1)),1),not(1)),f()),1),f())),lt(or(1,sub(f(),1)),1)),f()),1),1),gt(not(f()),1))),1),1),1)
sstore(not(f()),1)
}
function foo_singlereturn_1(in_1, in_2) -> out
@ -25,21 +38,27 @@
//
// {
// {
// let _1 := gt(not(pc()), 1)
// let _2 := pc()
// let _1 := gt(not(gcd(10, 15)), 1)
// let _2 := gcd(10, 15)
// let _3 := not(0)
// let _4 := lt(or(1, add(pc(), _3)), 1)
// let _5 := pc()
// let _6 := pc()
// pop(keccak256(pc(), or(gt(not(pc()), 1), 1)))
// let _4 := lt(or(1, add(gcd(10, 15), _3)), 1)
// let _5 := gcd(10, 15)
// let _6 := gcd(10, 15)
// pop(keccak256(gcd(10, 15), or(gt(not(gcd(10, 15)), 1), 1)))
// mstore(lt(or(gt(1, or(or(gt(or(or(or(gt(or(gt(_3, _6), 1), _5), _4), _2), 1), 1), _1), 1)), 1), 1), 1)
// sstore(not(pc()), 1)
// sstore(not(gcd(10, 15)), 1)
// sstore(0, 0)
// sstore(2, 1)
// pop(foo_singlereturn_1(calldataload(0), calldataload(3)))
// sstore(0, 0)
// sstore(3, 1)
// }
// function gcd(_a, _b) -> out
// {
// switch _b
// case 0 { out := _a }
// default { out := gcd(_b, mod(_a, _b)) }
// }
// function foo_singlereturn_1(in, in_1) -> out
// { extcodecopy(1, msize(), 1, 1) }
// }

View File

@ -1,11 +1,11 @@
{
{
let _13_71 := 1
let _17_72 := pc()
let _22_75 := pc()
let _25_76 := pc()
let _30_80 := pc()
let _32_81 := pc()
let _17_72 := msize()
let _22_75 := msize()
let _25_76 := msize()
let _30_80 := msize()
let _32_81 := msize()
// This should not be removed
pop(keccak256(1, 2))
let _104 := gt(not(_17_72), _13_71)
@ -22,11 +22,11 @@
// step: stackCompressor
//
// {
// let _17_72 := pc()
// let _22_75 := pc()
// let _25_76 := pc()
// let _30_80 := pc()
// let _32_81 := pc()
// let _17_72 := msize()
// let _22_75 := msize()
// let _25_76 := msize()
// let _30_80 := msize()
// let _32_81 := msize()
// pop(keccak256(1, 2))
// let _105 := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
// mstore(lt(or(gt(1, or(or(gt(or(or(or(gt(or(gt(_105, _32_81), 1), _30_80), lt(or(1, add(_25_76, _105)), 1)), _22_75), 1), 1), gt(not(_17_72), 1)), 1)), 1), 1), 1)

View File

@ -0,0 +1,7 @@
{
pop(pc())
}
// ====
// dialect: evmTyped
// ----
// Warning: (10-12): The "pc" instruction is deprecated and will be removed in the next breaking release.