mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Merge pull request #12584 from nishant-sachdeva/indexed_log_topic_differs_between_legacy_and_ir_if_explicitly_downcast
Code generators needed fixing of the cleanup process during typecasting
This commit is contained in:
		
						commit
						22116dfd0a
					
				| @ -16,6 +16,8 @@ Bugfixes: | ||||
|  * Code Generator: Fix ICE when doing an explicit conversion from ``string calldata`` to ``bytes``. | ||||
|  * Control Flow Graph: Perform proper virtual lookup for modifiers for uninitialized variable and unreachable code analysis. | ||||
|  * Immutables: Fix wrong error when the constructor of a base contract uses ``return`` and the parent contract contains immutable variables. | ||||
|  * IR Generator: Add missing cleanup during the conversion of fixed bytes types to smaller fixed bytes types. | ||||
|  * IR Generator: Add missing cleanup for indexed event arguments of value type. | ||||
|  * IR Generator: Fix IR syntax error when copying storage arrays of structs containing functions. | ||||
|  * Natspec: Fix ICE when overriding a struct getter with a Natspec-documented return value and the name in the struct is different. | ||||
|  * TypeChecker: Fix ICE when a constant variable declaration forward references a struct. | ||||
|  | ||||
| @ -3400,11 +3400,11 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to) | ||||
| 						.render(); | ||||
| 			else | ||||
| 			{ | ||||
| 				// clear for conversion to longer bytes
 | ||||
| 				solAssert(toCategory == Type::Category::FixedBytes, "Invalid type conversion requested."); | ||||
| 				FixedBytesType const& to = dynamic_cast<FixedBytesType const&>(_to); | ||||
| 				body = | ||||
| 					Whiskers("converted := <clean>(value)") | ||||
| 					("clean", cleanupFunction(from)) | ||||
| 					("clean", cleanupFunction((to.numBytes() <= from.numBytes()) ? to : from)) | ||||
| 					.render(); | ||||
| 			} | ||||
| 			break; | ||||
|  | ||||
| @ -1035,7 +1035,10 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) | ||||
| 						")\n"; | ||||
| 				} | ||||
| 				else | ||||
| 					indexedArgs.emplace_back(convert(arg, *paramTypes[i])); | ||||
| 				{ | ||||
| 					solAssert(parameterTypes[i]->sizeOnStack() == 1, ""); | ||||
| 					indexedArgs.emplace_back(convert(arg, *paramTypes[i], true)); | ||||
| 				} | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| @ -2724,14 +2727,14 @@ void IRGeneratorForStatements::assignInternalFunctionIDIfNotCalledDirectly( | ||||
| 	m_context.addToInternalDispatch(_referencedFunction); | ||||
| } | ||||
| 
 | ||||
| IRVariable IRGeneratorForStatements::convert(IRVariable const& _from, Type const& _to) | ||||
| IRVariable IRGeneratorForStatements::convert(IRVariable const& _from, Type const& _to, bool _forceCleanup) | ||||
| { | ||||
| 	if (_from.type() == _to) | ||||
| 	if (_from.type() == _to && !_forceCleanup) | ||||
| 		return _from; | ||||
| 	else | ||||
| 	{ | ||||
| 		IRVariable converted(m_context.newYulVariable(), _to); | ||||
| 		define(converted, _from); | ||||
| 		define(converted, _from, _forceCleanup); | ||||
| 		return converted; | ||||
| 	} | ||||
| } | ||||
| @ -2763,10 +2766,10 @@ void IRGeneratorForStatements::declare(IRVariable const& _var) | ||||
| 		appendCode() << "let " << _var.commaSeparatedList() << "\n"; | ||||
| } | ||||
| 
 | ||||
| void IRGeneratorForStatements::declareAssign(IRVariable const& _lhs, IRVariable const& _rhs, bool _declare) | ||||
| void IRGeneratorForStatements::declareAssign(IRVariable const& _lhs, IRVariable const& _rhs, bool _declare, bool _forceCleanup) | ||||
| { | ||||
| 	string output; | ||||
| 	if (_lhs.type() == _rhs.type()) | ||||
| 	if (_lhs.type() == _rhs.type() && !_forceCleanup) | ||||
| 		for (auto const& [stackItemName, stackItemType]: _lhs.type().stackItems()) | ||||
| 			if (stackItemType) | ||||
| 				declareAssign(_lhs.part(stackItemName), _rhs.part(stackItemName), _declare); | ||||
|  | ||||
| @ -86,7 +86,11 @@ public: | ||||
| 	IRVariable evaluateExpression(Expression const& _expression, Type const& _to); | ||||
| 
 | ||||
| 	/// Defines @a _var using the value of @a _value while performing type conversions, if required.
 | ||||
| 	void define(IRVariable const& _var, IRVariable const& _value) { declareAssign(_var, _value, true); } | ||||
| 	/// If @a _forceCleanup is set to true, it also cleans the value of the variable after the conversion.
 | ||||
| 	void define(IRVariable const& _var, IRVariable const& _value, bool _forceCleanup = false) | ||||
| 	{ | ||||
| 		declareAssign(_var, _value, true, _forceCleanup); | ||||
| 	} | ||||
| 
 | ||||
| 	/// @returns the name of a function that computes the value of the given constant
 | ||||
| 	/// and also generates the function.
 | ||||
| @ -162,8 +166,8 @@ private: | ||||
| 	); | ||||
| 
 | ||||
| 	/// Generates the required conversion code and @returns an IRVariable referring to the value of @a _variable
 | ||||
| 	/// converted to type @a _to.
 | ||||
| 	IRVariable convert(IRVariable const& _variable, Type const& _to); | ||||
| 	/// If @a _forceCleanup is set to true, it also cleans the value of the variable after the conversion.
 | ||||
| 	IRVariable convert(IRVariable const& _variable, Type const& _to, bool _forceCleanup = false); | ||||
| 
 | ||||
| 	/// @returns a Yul expression representing the current value of @a _expression,
 | ||||
| 	/// converted to type @a _to if it does not yet have that type.
 | ||||
| @ -179,7 +183,7 @@ private: | ||||
| 	/// Declares variable @a _var.
 | ||||
| 	void declare(IRVariable const& _var); | ||||
| 
 | ||||
| 	void declareAssign(IRVariable const& _var, IRVariable const& _value, bool _define); | ||||
| 	void declareAssign(IRVariable const& _var, IRVariable const& _value, bool _define, bool _forceCleanup = false); | ||||
| 
 | ||||
| 	/// @returns an IRVariable with the zero
 | ||||
| 	/// value of @a _type.
 | ||||
|  | ||||
| @ -11,7 +11,6 @@ contract C { | ||||
|     } | ||||
| } | ||||
| // ==== | ||||
| // compileToEwasm: also | ||||
| // compileViaYul: also | ||||
| // compileViaYul: false | ||||
| // ---- | ||||
| // f() -> "\xff\xff\xff\xff" | ||||
| // f() -> 0xffffffff00000000000000000000000000000000000000000000000000000000 | ||||
| @ -0,0 +1,14 @@ | ||||
| contract C { | ||||
|     function f() public pure returns (bytes32 r) { | ||||
|         bytes4 x = 0xffffffff; | ||||
|         bytes2 y = bytes2(x); | ||||
|         assembly { | ||||
|             r := y | ||||
|         } | ||||
|     } | ||||
| } | ||||
| // ==== | ||||
| // compileToEwasm: also | ||||
| // compileViaYul: true | ||||
| // ---- | ||||
| // f() -> 0xffff000000000000000000000000000000000000000000000000000000000000 | ||||
| @ -0,0 +1,23 @@ | ||||
| contract C { | ||||
|     function f() public pure returns (uint32 y) { | ||||
|         uint8 x = uint8(uint256(0x31313131313131313131313131313131)); | ||||
|         assembly { y := x } | ||||
|     } | ||||
| 
 | ||||
|     function g() public pure returns (bytes32 y) { | ||||
|         bytes1 x = bytes1(bytes16(0x31313131313131313131313131313131)); | ||||
|         assembly { y := x } | ||||
|     } | ||||
| 
 | ||||
|     function h() external returns (bytes32 y) { | ||||
|         bytes1 x; | ||||
|         assembly { x := sub(0,1) } | ||||
|         y = x; | ||||
|     } | ||||
| } | ||||
| // ==== | ||||
| // compileViaYul: true | ||||
| // ---- | ||||
| // f() -> 0x31 | ||||
| // g() -> 0x3100000000000000000000000000000000000000000000000000000000000000 | ||||
| // h() -> 0xff00000000000000000000000000000000000000000000000000000000000000 | ||||
| @ -0,0 +1,19 @@ | ||||
| contract C { | ||||
|     event ev0(bytes1 indexed); | ||||
|     constructor() { | ||||
|         emit ev0(bytes1(bytes16(0x31313131313131313131313131313131))); | ||||
|     } | ||||
|     function j() external { | ||||
|         bytes1 x; | ||||
|         assembly { x := 0x3131313131313131313131313131313131313131313131313131313131313131 } | ||||
|         emit ev0(x); | ||||
|     } | ||||
| } | ||||
| // ==== | ||||
| // compileViaYul: also | ||||
| // ---- | ||||
| // constructor() -> | ||||
| // ~ emit ev0(bytes1): #"1" | ||||
| // gas legacy: 168735 | ||||
| // j() -> | ||||
| // ~ emit ev0(bytes1): #"1" | ||||
| @ -115,7 +115,7 @@ contract ERC20 { | ||||
| // ---- | ||||
| // constructor() | ||||
| // ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14 | ||||
| // gas irOptimized: 442239 | ||||
| // gas irOptimized: 447831 | ||||
| // gas legacy: 861559 | ||||
| // gas legacyOptimized: 420959 | ||||
| // totalSupply() -> 20 | ||||
|  | ||||
| @ -98,7 +98,7 @@ contract ERC20 { | ||||
| // ---- | ||||
| // constructor() | ||||
| // ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14 | ||||
| // gas irOptimized: 437697 | ||||
| // gas irOptimized: 443295 | ||||
| // gas legacy: 833310 | ||||
| // gas legacyOptimized: 416135 | ||||
| // totalSupply() -> 20 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user