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