mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Merge pull request #2688 from chriseth/toBytesConversion
Allow explicit conversions bytes <-> string.
This commit is contained in:
		
						commit
						4ce09762c7
					
				
							
								
								
									
										10
									
								
								AST.cpp
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								AST.cpp
									
									
									
									
									
								
							| @ -844,9 +844,15 @@ void FunctionCall::checkTypeRequirements(TypePointers const*) | |||||||
| 			BOOST_THROW_EXCEPTION(createTypeError("Exactly one argument expected for explicit type conversion.")); | 			BOOST_THROW_EXCEPTION(createTypeError("Exactly one argument expected for explicit type conversion.")); | ||||||
| 		if (!isPositionalCall) | 		if (!isPositionalCall) | ||||||
| 			BOOST_THROW_EXCEPTION(createTypeError("Type conversion cannot allow named arguments.")); | 			BOOST_THROW_EXCEPTION(createTypeError("Type conversion cannot allow named arguments.")); | ||||||
| 		if (!m_arguments.front()->getType()->isExplicitlyConvertibleTo(*type.getActualType())) |  | ||||||
| 			BOOST_THROW_EXCEPTION(createTypeError("Explicit type conversion not allowed.")); |  | ||||||
| 		m_type = type.getActualType(); | 		m_type = type.getActualType(); | ||||||
|  | 		auto argType = m_arguments.front()->getType(); | ||||||
|  | 		if (auto argRefType = dynamic_cast<ReferenceType const*>(argType.get())) | ||||||
|  | 			// do not change the data location when converting
 | ||||||
|  | 			// (data location cannot yet be specified for type conversions)
 | ||||||
|  | 			m_type = ReferenceType::copyForLocationIfReference(argRefType->location(), m_type); | ||||||
|  | 		if (!argType->isExplicitlyConvertibleTo(*m_type)) | ||||||
|  | 			BOOST_THROW_EXCEPTION(createTypeError("Explicit type conversion not allowed.")); | ||||||
|  | 
 | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -404,7 +404,7 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp | |||||||
| 		case DataLocation::Storage: | 		case DataLocation::Storage: | ||||||
| 			// Other cases are done explicitly in LValue::storeValue, and only possible by assignment.
 | 			// Other cases are done explicitly in LValue::storeValue, and only possible by assignment.
 | ||||||
| 			solAssert( | 			solAssert( | ||||||
| 				targetType.isPointer() && | 				(targetType.isPointer() || (typeOnStack.isByteArray() && targetType.isByteArray())) && | ||||||
| 				typeOnStack.location() == DataLocation::Storage, | 				typeOnStack.location() == DataLocation::Storage, | ||||||
| 				"Invalid conversion to storage type." | 				"Invalid conversion to storage type." | ||||||
| 			); | 			); | ||||||
| @ -469,6 +469,13 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp | |||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
|  | 		case DataLocation::CallData: | ||||||
|  | 			solAssert( | ||||||
|  | 					targetType.isByteArray() && | ||||||
|  | 					typeOnStack.isByteArray() && | ||||||
|  | 					typeOnStack.location() == DataLocation::CallData, | ||||||
|  | 				"Invalid conversion to calldata type."); | ||||||
|  | 			break; | ||||||
| 		default: | 		default: | ||||||
| 			solAssert( | 			solAssert( | ||||||
| 				false, | 				false, | ||||||
|  | |||||||
							
								
								
									
										15
									
								
								Types.cpp
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								Types.cpp
									
									
									
									
									
								
							| @ -789,6 +789,21 @@ bool ArrayType::isImplicitlyConvertibleTo(const Type& _convertTo) const | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool ArrayType::isExplicitlyConvertibleTo(const Type& _convertTo) const | ||||||
|  | { | ||||||
|  | 	if (isImplicitlyConvertibleTo(_convertTo)) | ||||||
|  | 		return true; | ||||||
|  | 	// allow conversion bytes <-> string
 | ||||||
|  | 	if (_convertTo.getCategory() != getCategory()) | ||||||
|  | 		return false; | ||||||
|  | 	auto& convertTo = dynamic_cast<ArrayType const&>(_convertTo); | ||||||
|  | 	if (convertTo.location() != location()) | ||||||
|  | 		return false; | ||||||
|  | 	if (!isByteArray() || !convertTo.isByteArray()) | ||||||
|  | 		return false; | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| bool ArrayType::operator==(Type const& _other) const | bool ArrayType::operator==(Type const& _other) const | ||||||
| { | { | ||||||
| 	if (_other.getCategory() != getCategory()) | 	if (_other.getCategory() != getCategory()) | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								Types.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								Types.h
									
									
									
									
									
								
							| @ -477,6 +477,7 @@ public: | |||||||
| 	{} | 	{} | ||||||
| 
 | 
 | ||||||
| 	virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override; | 	virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override; | ||||||
|  | 	virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override; | ||||||
| 	virtual bool operator==(const Type& _other) const override; | 	virtual bool operator==(const Type& _other) const override; | ||||||
| 	virtual unsigned getCalldataEncodedSize(bool _padded) const override; | 	virtual unsigned getCalldataEncodedSize(bool _padded) const override; | ||||||
| 	virtual bool isDynamicallySized() const override { return m_hasDynamicLength; } | 	virtual bool isDynamicallySized() const override { return m_hasDynamicLength; } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user