mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Inaccessible dynamic types
This commit is contained in:
		
							parent
							
								
									7dab890278
								
							
						
					
					
						commit
						754a992500
					
				| @ -2037,29 +2037,20 @@ FunctionTypePointer FunctionType::asMemberFunction(bool _inLibrary, bool _bound) | ||||
| 			location = Location::DelegateCall; | ||||
| 	} | ||||
| 
 | ||||
| 	TypePointers returnParameterTypes; | ||||
| 	vector<string> returnParameterNames; | ||||
| 	if (location == Location::Internal) | ||||
| 	TypePointers returnParameterTypes = m_returnParameterTypes; | ||||
| 	if (location != Location::Internal) | ||||
| 	{ | ||||
| 		returnParameterNames = m_returnParameterNames; | ||||
| 		returnParameterTypes = m_returnParameterTypes; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		// Removes dynamic types.
 | ||||
| 		for (size_t i = 0; i < m_returnParameterTypes.size(); ++i) | ||||
| 			if (!m_returnParameterTypes[i]->isDynamicallySized()) | ||||
| 			{ | ||||
| 				returnParameterTypes.push_back(m_returnParameterTypes[i]); | ||||
| 				returnParameterNames.push_back(m_returnParameterNames[i]); | ||||
| 			} | ||||
| 		// Alter dynamic types to be non-accessible.
 | ||||
| 		for (auto& param: returnParameterTypes) | ||||
| 			if (param->isDynamicallySized()) | ||||
| 				param = make_shared<InaccessibleDynamicType>(); | ||||
| 	} | ||||
| 
 | ||||
| 	return make_shared<FunctionType>( | ||||
| 		parameterTypes, | ||||
| 		returnParameterTypes, | ||||
| 		m_parameterNames, | ||||
| 		returnParameterNames, | ||||
| 		m_returnParameterNames, | ||||
| 		location, | ||||
| 		m_arbitraryParameters, | ||||
| 		m_declaration, | ||||
|  | ||||
| @ -137,7 +137,8 @@ public: | ||||
| 	{ | ||||
| 		Integer, RationalNumber, StringLiteral, Bool, FixedPoint, Array, | ||||
| 		FixedBytes, Contract, Struct, Function, Enum, Tuple, | ||||
| 		Mapping, TypeType, Modifier, Magic, Module | ||||
| 		Mapping, TypeType, Modifier, Magic, Module, | ||||
| 		InaccessibleDynamic | ||||
| 	}; | ||||
| 
 | ||||
| 	/// @{
 | ||||
| @ -1081,5 +1082,25 @@ private: | ||||
| 	Kind m_kind; | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * Special type that is used for dynamic types in returns from external function calls | ||||
|  * (The EVM currently cannot access dynamically-sized return values). | ||||
|  */ | ||||
| class InaccessibleDynamicType: public Type | ||||
| { | ||||
| public: | ||||
| 	virtual Category category() const override { return Category::InaccessibleDynamic; } | ||||
| 
 | ||||
| 	virtual bool isImplicitlyConvertibleTo(Type const&) const override { return false; } | ||||
| 	virtual bool isExplicitlyConvertibleTo(Type const&) const override { return false; } | ||||
| 	virtual unsigned calldataEncodedSize(bool _padded) const override { (void)_padded; return 32; } | ||||
| 	virtual bool canBeStored() const override { return false; } | ||||
| 	virtual bool canLiveOutsideStorage() const override { return false; } | ||||
| 	virtual bool isValueType() const override { return true; } | ||||
| 	virtual unsigned sizeOnStack() const override { return 1; } | ||||
| 	virtual std::string toString(bool) const override { return "inaccessible dynamic type"; } | ||||
| 	virtual TypePointer decodingType() const override { return std::make_shared<IntegerType>(256); } | ||||
| }; | ||||
| 
 | ||||
| } | ||||
| } | ||||
|  | ||||
| @ -6793,6 +6793,25 @@ BOOST_AUTO_TEST_CASE(cleanup_bytes_types) | ||||
| 	BOOST_CHECK(callContractFunction("f(bytes2,uint16)", string("abc"), u256(0x040102)) == encodeArgs(0)); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(skip_dynamic_types) | ||||
| { | ||||
| 	// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.
 | ||||
| 	char const* sourceCode = R"( | ||||
| 		contract C { | ||||
| 			function f() returns (uint, uint[], uint) { | ||||
| 				return (7, new uint[](2), 8); | ||||
| 			} | ||||
| 			function g() returns (uint, uint) { | ||||
| 				// Previous implementation "moved" b to the second place and did not skip.
 | ||||
| 				var (a, _, b) = this.f(); | ||||
| 				return (a, b); | ||||
| 			} | ||||
| 		} | ||||
| 	)"; | ||||
| 	compileAndRun(sourceCode, 0, "C"); | ||||
| 	BOOST_CHECK(callContractFunction("g()") == encodeArgs(u256(7), u256(8))); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_SUITE_END() | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -2154,6 +2154,8 @@ BOOST_AUTO_TEST_CASE(dynamic_return_types_not_possible) | ||||
| 			function f(uint) returns (string); | ||||
| 			function g() { | ||||
| 				var (x,) = this.f(2); | ||||
| 				// we can assign to x but it is not usable.
 | ||||
| 				bytes(x).length; | ||||
| 			} | ||||
| 		} | ||||
| 	)"; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user