mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Merge pull request #8913 from ethereum/yul-remove-pc-instr
Mark EVM instruction `pc()` as deprecated when used in inline assembly.
This commit is contained in:
		
						commit
						afa873fe9f
					
				| @ -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: | ||||
|  | ||||
| @ -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; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -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 ( | ||||
|  | ||||
| @ -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); | ||||
| 
 | ||||
|  | ||||
| @ -90,7 +90,6 @@ void MSizeFinder::operator()(FunctionCall const& _functionCall) | ||||
| 			m_msizeFound = true; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| map<YulString, SideEffects> SideEffectsPropagator::sideEffects( | ||||
| 	Dialect const& _dialect, | ||||
| 	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(returndatasize()) | ||||
| 	pop(sload(0)) | ||||
| 	pop(pc()) | ||||
| 	pop(msize()) | ||||
| 	pop(mload(0)) | ||||
| 	pop(sload(0)) | ||||
|  | ||||
| @ -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) } | ||||
| // } | ||||
|  | ||||
| @ -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) | ||||
|  | ||||
							
								
								
									
										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