Merge remote-tracking branch 'origin/develop' into breaking

This commit is contained in:
chriseth
2022-04-13 17:08:27 +02:00
186 changed files with 3081 additions and 976 deletions
@@ -297,7 +297,7 @@ void DeclarationTypeChecker::endVisit(ArrayTypeName const& _typeName)
else if (optional<ConstantEvaluator::TypedRational> value = ConstantEvaluator::evaluate(m_errorReporter, *length))
lengthValue = value->value;
if (!lengthValue || lengthValue > TypeProvider::uint256()->max())
if (!lengthValue)
m_errorReporter.typeError(
5462_error,
length->location(),
@@ -309,6 +309,12 @@ void DeclarationTypeChecker::endVisit(ArrayTypeName const& _typeName)
m_errorReporter.typeError(3208_error, length->location(), "Array with fractional length specified.");
else if (*lengthValue < 0)
m_errorReporter.typeError(3658_error, length->location(), "Array with negative length specified.");
else if (lengthValue > TypeProvider::uint256()->max())
m_errorReporter.typeError(
1847_error,
length->location(),
"Array length too large, maximum is 2**256 - 1."
);
_typeName.annotation().type = TypeProvider::array(
DataLocation::Storage,
+33 -33
View File
@@ -1658,24 +1658,21 @@ bool TypeChecker::visit(UnaryOperation const& _operation)
Type const* subExprType = type(_operation.subExpression());
TypeResult result = subExprType->unaryOperatorResult(op);
Type const* t = result;
if (!result)
{
string description = "Unary operator " +
string(TokenTraits::toString(op)) +
" cannot be applied to type " +
subExprType->toString() +
(result.message().empty() ? "" : (": " + result.message()));
string description = "Unary operator " + string(TokenTraits::toString(op)) + " cannot be applied to type " + subExprType->toString();
if (!result.message().empty())
description += ". " + result.message();
if (modifying)
// Cannot just report the error, ignore the unary operator, and continue,
// because the sub-expression was already processed with requireLValue()
m_errorReporter.fatalTypeError(9767_error, _operation.location(), description);
else
m_errorReporter.typeError(4907_error, _operation.location(), description);
t = subExprType;
_operation.annotation().type = subExprType;
}
_operation.annotation().type = t;
else
_operation.annotation().type = result.get();
_operation.annotation().isConstant = false;
_operation.annotation().isPure = !modifying && *_operation.subExpression().annotation().isPure;
_operation.annotation().isLValue = false;
@@ -2111,57 +2108,60 @@ void TypeChecker::typeCheckABIEncodeCallFunction(FunctionCall const& _functionCa
return;
}
auto const functionPointerType = dynamic_cast<FunctionTypePointer>(type(*arguments.front()));
if (!functionPointerType)
FunctionType const* externalFunctionType = nullptr;
if (auto const functionPointerType = dynamic_cast<FunctionTypePointer>(type(*arguments.front())))
{
// this cannot be a library function, that is checked below
externalFunctionType = functionPointerType->asExternallyCallableFunction(false);
solAssert(externalFunctionType->kind() == functionPointerType->kind());
}
else
{
m_errorReporter.typeError(
5511_error,
arguments.front()->location(),
"Expected first argument to be a function pointer, not \"" +
type(*arguments.front())->canonicalName() +
type(*arguments.front())->toString() +
"\"."
);
return;
}
if (
functionPointerType->kind() != FunctionType::Kind::External &&
functionPointerType->kind() != FunctionType::Kind::Declaration
externalFunctionType->kind() != FunctionType::Kind::External &&
externalFunctionType->kind() != FunctionType::Kind::Declaration
)
{
string msg = "Expected regular external function type, or external view on public function.";
if (functionPointerType->kind() == FunctionType::Kind::Internal)
if (externalFunctionType->kind() == FunctionType::Kind::Internal)
msg += " Provided internal function.";
else if (functionPointerType->kind() == FunctionType::Kind::DelegateCall)
else if (externalFunctionType->kind() == FunctionType::Kind::DelegateCall)
msg += " Cannot use library functions for abi.encodeCall.";
else if (functionPointerType->kind() == FunctionType::Kind::Creation)
else if (externalFunctionType->kind() == FunctionType::Kind::Creation)
msg += " Provided creation function.";
else
msg += " Cannot use special function.";
SecondarySourceLocation ssl{};
if (functionPointerType->hasDeclaration())
if (externalFunctionType->hasDeclaration())
{
ssl.append("Function is declared here:", functionPointerType->declaration().location());
ssl.append("Function is declared here:", externalFunctionType->declaration().location());
if (
functionPointerType->declaration().visibility() == Visibility::Public &&
functionPointerType->declaration().scope() == m_currentContract
externalFunctionType->declaration().visibility() == Visibility::Public &&
externalFunctionType->declaration().scope() == m_currentContract
)
msg += " Did you forget to prefix \"this.\"?";
else if (util::contains(
m_currentContract->annotation().linearizedBaseContracts,
functionPointerType->declaration().scope()
) && functionPointerType->declaration().scope() != m_currentContract)
externalFunctionType->declaration().scope()
) && externalFunctionType->declaration().scope() != m_currentContract)
msg += " Functions from base contracts have to be external.";
}
m_errorReporter.typeError(3509_error, arguments[0]->location(), ssl, msg);
return;
}
solAssert(!functionPointerType->takesArbitraryParameters(), "Function must have fixed parameters.");
solAssert(!externalFunctionType->takesArbitraryParameters(), "Function must have fixed parameters.");
// Tuples with only one component become that component
vector<ASTPointer<Expression const>> callArguments;
@@ -2174,14 +2174,14 @@ void TypeChecker::typeCheckABIEncodeCallFunction(FunctionCall const& _functionCa
else
callArguments.push_back(arguments[1]);
if (functionPointerType->parameterTypes().size() != callArguments.size())
if (externalFunctionType->parameterTypes().size() != callArguments.size())
{
if (tupleType)
m_errorReporter.typeError(
7788_error,
_functionCall.location(),
"Expected " +
to_string(functionPointerType->parameterTypes().size()) +
to_string(externalFunctionType->parameterTypes().size()) +
" instead of " +
to_string(callArguments.size()) +
" components for the tuple parameter."
@@ -2191,18 +2191,18 @@ void TypeChecker::typeCheckABIEncodeCallFunction(FunctionCall const& _functionCa
7515_error,
_functionCall.location(),
"Expected a tuple with " +
to_string(functionPointerType->parameterTypes().size()) +
to_string(externalFunctionType->parameterTypes().size()) +
" components instead of a single non-tuple parameter."
);
}
// Use min() to check as much as we can before failing fatally
size_t const numParameters = min(callArguments.size(), functionPointerType->parameterTypes().size());
size_t const numParameters = min(callArguments.size(), externalFunctionType->parameterTypes().size());
for (size_t i = 0; i < numParameters; i++)
{
Type const& argType = *type(*callArguments[i]);
BoolResult result = argType.isImplicitlyConvertibleTo(*functionPointerType->parameterTypes()[i]);
BoolResult result = argType.isImplicitlyConvertibleTo(*externalFunctionType->parameterTypes()[i]);
if (!result)
m_errorReporter.typeError(
5407_error,
@@ -2212,7 +2212,7 @@ void TypeChecker::typeCheckABIEncodeCallFunction(FunctionCall const& _functionCa
" from \"" +
argType.toString() +
"\" to \"" +
functionPointerType->parameterTypes()[i]->toString() +
externalFunctionType->parameterTypes()[i]->toString() +
"\"" +
(result.message().empty() ? "." : ": " + result.message())
);