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."));
if (!isPositionalCall)
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();
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;
}

View File

@ -404,7 +404,7 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp
case DataLocation::Storage:
// Other cases are done explicitly in LValue::storeValue, and only possible by assignment.
solAssert(
targetType.isPointer() &&
(targetType.isPointer() || (typeOnStack.isByteArray() && targetType.isByteArray())) &&
typeOnStack.location() == DataLocation::Storage,
"Invalid conversion to storage type."
);
@ -469,6 +469,13 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp
}
break;
}
case DataLocation::CallData:
solAssert(
targetType.isByteArray() &&
typeOnStack.isByteArray() &&
typeOnStack.location() == DataLocation::CallData,
"Invalid conversion to calldata type.");
break;
default:
solAssert(
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
{
if (_other.getCategory() != getCategory())

View File

@ -477,6 +477,7 @@ public:
{}
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 unsigned getCalldataEncodedSize(bool _padded) const override;
virtual bool isDynamicallySized() const override { return m_hasDynamicLength; }