Merge pull request #2688 from chriseth/toBytesConversion

Allow explicit conversions bytes <-> string.
This commit is contained in:
chriseth 2015-08-05 17:19:19 +02:00
commit 4ce09762c7
4 changed files with 32 additions and 3 deletions

10
AST.cpp
View File

@ -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;
} }

View File

@ -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,

View File

@ -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())

View File

@ -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; }