Fix ICE for 32-byte hex literals and zero literals in bytes.concat() by disallowing them

This commit is contained in:
Kamil Śliwak
2021-06-29 14:48:42 +02:00
parent 1d1d74bd0e
commit 6a50d088a0
8 changed files with 75 additions and 44 deletions
+8 -4
View File
@@ -2033,11 +2033,14 @@ void TypeChecker::typeCheckBytesConcatFunction(
typeCheckFunctionGeneralChecks(_functionCall, _functionType);
for (shared_ptr<Expression const> const& argument: _functionCall.arguments())
if (
Type const* argumentType = type(*argument);
{
Type const* argumentType = type(*argument);
bool notConvertibleToBytes =
!argumentType->isImplicitlyConvertibleTo(*TypeProvider::fixedBytes(32)) &&
!argumentType->isImplicitlyConvertibleTo(*TypeProvider::bytesMemory())
)
!argumentType->isImplicitlyConvertibleTo(*TypeProvider::bytesMemory());
bool numberLiteral = (dynamic_cast<RationalNumberType const*>(argumentType) != nullptr);
if (notConvertibleToBytes || numberLiteral)
m_errorReporter.typeError(
8015_error,
argument->location(),
@@ -2045,6 +2048,7 @@ void TypeChecker::typeCheckBytesConcatFunction(
"bytes or fixed bytes type is required, but " +
argumentType->toString(true) + " provided."
);
}
}
void TypeChecker::typeCheckFunctionGeneralChecks(
+1 -5
View File
@@ -1086,13 +1086,9 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
literalType && literalType->value().size() <= 32
)
targetTypes.emplace_back(TypeProvider::fixedBytes(static_cast<unsigned>(literalType->value().size())));
else if (auto const* literalType = dynamic_cast<RationalNumberType const*>(argument->annotation().type))
{
solAssert(literalType->value() == 0, "");
targetTypes.emplace_back(TypeProvider::fixedBytes(1));
}
else
{
solAssert(!dynamic_cast<RationalNumberType const*>(argument->annotation().type), "");
solAssert(argument->annotation().type->isImplicitlyConvertibleTo(*TypeProvider::bytesMemory()), "");
targetTypes.emplace_back(TypeProvider::bytesMemory());
}
+1 -5
View File
@@ -2476,13 +2476,9 @@ string YulUtilFunctions::bytesConcatFunction(vector<Type const*> const& _argumen
literalType && literalType->value().size() <= 32
)
targetTypes.emplace_back(TypeProvider::fixedBytes(static_cast<unsigned>(literalType->value().size())));
else if (auto const* literalType = dynamic_cast<RationalNumberType const*>(argumentType))
{
solAssert(literalType->value() == 0, "");
targetTypes.emplace_back(TypeProvider::fixedBytes(1));
}
else
{
solAssert(!dynamic_cast<RationalNumberType const*>(argumentType), "");
solAssert(argumentType->isImplicitlyConvertibleTo(*TypeProvider::bytesMemory()), "");
targetTypes.emplace_back(TypeProvider::bytesMemory());
}