mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Mark EVM instruction pc()
as deprecated when used in inline assembly.
This commit is contained in:
parent
b488627c79
commit
b7fa5d5040
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
Language Features:
|
Language Features:
|
||||||
* Permit calldata location for all variables.
|
* Permit calldata location for all variables.
|
||||||
|
* Yul: EVM instruction `pc()` is marked deprecated and will be removed in the next breaking release.
|
||||||
|
|
||||||
|
|
||||||
Compiler Features:
|
Compiler Features:
|
||||||
|
@ -273,6 +273,7 @@ bool SyntaxChecker::visit(InlineAssembly const& _inlineAssembly)
|
|||||||
"The msize instruction cannot be used when the Yul optimizer is activated because "
|
"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."
|
"it can change its semantics. Either disable the Yul optimizer or do not use the instruction."
|
||||||
);
|
);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect(Dialect const& _dialect,
|
|||||||
{},
|
{},
|
||||||
_object.dataNames()
|
_object.dataNames()
|
||||||
).analyze(*_object.code);
|
).analyze(*_object.code);
|
||||||
yulAssert(success && errorList.empty(), "Invalid assembly/yul code.");
|
yulAssert(success && !errors.hasErrors(), "Invalid assembly/yul code.");
|
||||||
return analysisInfo;
|
return analysisInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,6 +259,8 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
|
|||||||
returnTypes = &f->returns;
|
returnTypes = &f->returns;
|
||||||
if (f->literalArguments)
|
if (f->literalArguments)
|
||||||
needsLiteralArguments = &f->literalArguments.value();
|
needsLiteralArguments = &f->literalArguments.value();
|
||||||
|
|
||||||
|
warnOnInstructions(_funCall);
|
||||||
}
|
}
|
||||||
else if (!m_currentScope->lookup(_funCall.functionName.name, GenericVisitor{
|
else if (!m_currentScope->lookup(_funCall.functionName.name, GenericVisitor{
|
||||||
[&](Scope::Variable const&)
|
[&](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.");
|
declarationError(_funCall.functionName.location, "Function not found.");
|
||||||
yulAssert(!watcher.ok(), "Expected a reported error.");
|
yulAssert(!watcher.ok(), "Expected a reported error.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameterTypes && _funCall.arguments.size() != parameterTypes->size())
|
if (parameterTypes && _funCall.arguments.size() != parameterTypes->size())
|
||||||
typeError(
|
typeError(
|
||||||
_funCall.functionName.location,
|
_funCall.functionName.location,
|
||||||
@ -553,6 +556,14 @@ bool AsmAnalyzer::warnOnInstructions(evmasm::Instruction _instr, SourceLocation
|
|||||||
errorForVM("only available for Constantinople-compatible");
|
errorForVM("only available for Constantinople-compatible");
|
||||||
else if (_instr == evmasm::Instruction::CHAINID && !m_evmVersion.hasChainID())
|
else if (_instr == evmasm::Instruction::CHAINID && !m_evmVersion.hasChainID())
|
||||||
errorForVM("only available for Istanbul-compatible");
|
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())
|
else if (_instr == evmasm::Instruction::SELFBALANCE && !m_evmVersion.hasSelfBalance())
|
||||||
errorForVM("only available for Istanbul-compatible");
|
errorForVM("only available for Istanbul-compatible");
|
||||||
else if (
|
else if (
|
||||||
|
@ -112,6 +112,11 @@ private:
|
|||||||
bool warnOnInstructions(evmasm::Instruction _instr, langutil::SourceLocation const& _location);
|
bool warnOnInstructions(evmasm::Instruction _instr, langutil::SourceLocation const& _location);
|
||||||
bool warnOnInstructions(std::string const& _instrIdentifier, 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 typeError(langutil::SourceLocation const& _location, std::string const& _description);
|
||||||
void declarationError(langutil::SourceLocation const& _location, std::string const& _description);
|
void declarationError(langutil::SourceLocation const& _location, std::string const& _description);
|
||||||
|
|
||||||
|
@ -90,7 +90,6 @@ void MSizeFinder::operator()(FunctionCall const& _functionCall)
|
|||||||
m_msizeFound = true;
|
m_msizeFound = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
map<YulString, SideEffects> SideEffectsPropagator::sideEffects(
|
map<YulString, SideEffects> SideEffectsPropagator::sideEffects(
|
||||||
Dialect const& _dialect,
|
Dialect const& _dialect,
|
||||||
CallGraph const& _directCallGraph
|
CallGraph const& _directCallGraph
|
||||||
|
9
test/libsolidity/syntaxTests/inlineAssembly/pc.sol
Normal file
9
test/libsolidity/syntaxTests/inlineAssembly/pc.sol
Normal 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.
|
@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
sstore(0, pc())
|
|
||||||
}
|
|
||||||
// ----
|
|
||||||
// Trace:
|
|
||||||
// INVALID()
|
|
||||||
// Memory dump:
|
|
||||||
// Storage dump:
|
|
@ -6,7 +6,6 @@
|
|||||||
pop(extcodehash(0))
|
pop(extcodehash(0))
|
||||||
pop(returndatasize())
|
pop(returndatasize())
|
||||||
pop(sload(0))
|
pop(sload(0))
|
||||||
pop(pc())
|
|
||||||
pop(msize())
|
pop(msize())
|
||||||
pop(mload(0))
|
pop(mload(0))
|
||||||
pop(sload(0))
|
pop(sload(0))
|
||||||
|
@ -1,10 +1,23 @@
|
|||||||
{
|
{
|
||||||
let a
|
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
|
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)
|
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(pc()),1)
|
sstore(not(f()),1)
|
||||||
}
|
}
|
||||||
|
|
||||||
function foo_singlereturn_1(in_1, in_2) -> out
|
function foo_singlereturn_1(in_1, in_2) -> out
|
||||||
@ -25,21 +38,27 @@
|
|||||||
//
|
//
|
||||||
// {
|
// {
|
||||||
// {
|
// {
|
||||||
// let _1 := gt(not(pc()), 1)
|
// let _1 := gt(not(gcd(10, 15)), 1)
|
||||||
// let _2 := pc()
|
// let _2 := gcd(10, 15)
|
||||||
// let _3 := not(0)
|
// let _3 := not(0)
|
||||||
// let _4 := lt(or(1, add(pc(), _3)), 1)
|
// let _4 := lt(or(1, add(gcd(10, 15), _3)), 1)
|
||||||
// let _5 := pc()
|
// let _5 := gcd(10, 15)
|
||||||
// let _6 := pc()
|
// let _6 := gcd(10, 15)
|
||||||
// pop(keccak256(pc(), or(gt(not(pc()), 1), 1)))
|
// 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)
|
// 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(0, 0)
|
||||||
// sstore(2, 1)
|
// sstore(2, 1)
|
||||||
// pop(foo_singlereturn_1(calldataload(0), calldataload(3)))
|
// pop(foo_singlereturn_1(calldataload(0), calldataload(3)))
|
||||||
// sstore(0, 0)
|
// sstore(0, 0)
|
||||||
// sstore(3, 1)
|
// 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
|
// function foo_singlereturn_1(in, in_1) -> out
|
||||||
// { extcodecopy(1, msize(), 1, 1) }
|
// { extcodecopy(1, msize(), 1, 1) }
|
||||||
// }
|
// }
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
let _13_71 := 1
|
let _13_71 := 1
|
||||||
let _17_72 := pc()
|
let _17_72 := msize()
|
||||||
let _22_75 := pc()
|
let _22_75 := msize()
|
||||||
let _25_76 := pc()
|
let _25_76 := msize()
|
||||||
let _30_80 := pc()
|
let _30_80 := msize()
|
||||||
let _32_81 := pc()
|
let _32_81 := msize()
|
||||||
// This should not be removed
|
// This should not be removed
|
||||||
pop(keccak256(1, 2))
|
pop(keccak256(1, 2))
|
||||||
let _104 := gt(not(_17_72), _13_71)
|
let _104 := gt(not(_17_72), _13_71)
|
||||||
@ -22,11 +22,11 @@
|
|||||||
// step: stackCompressor
|
// step: stackCompressor
|
||||||
//
|
//
|
||||||
// {
|
// {
|
||||||
// let _17_72 := pc()
|
// let _17_72 := msize()
|
||||||
// let _22_75 := pc()
|
// let _22_75 := msize()
|
||||||
// let _25_76 := pc()
|
// let _25_76 := msize()
|
||||||
// let _30_80 := pc()
|
// let _30_80 := msize()
|
||||||
// let _32_81 := pc()
|
// let _32_81 := msize()
|
||||||
// pop(keccak256(1, 2))
|
// pop(keccak256(1, 2))
|
||||||
// let _105 := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
// 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)
|
// 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)
|
||||||
|
7
test/libyul/yulSyntaxTests/pc.yul
Normal file
7
test/libyul/yulSyntaxTests/pc.yul
Normal 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.
|
Loading…
Reference in New Issue
Block a user