Merge pull request #5957 from ethereum/function-param-fix

Ensure function parameter names always matches parameter types length
This commit is contained in:
chriseth 2019-02-11 15:45:28 +01:00 committed by GitHub
commit b5a2c66771
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 71 additions and 31 deletions

View File

@ -1224,10 +1224,10 @@ bool TypeChecker::visit(TupleExpression const& _tuple)
if (!dynamic_cast<RationalNumberType const&>(*types[i]).mobileType())
m_errorReporter.fatalTypeError(components[i]->location(), "Invalid rational number.");
if (_tuple.isInlineArray())
solAssert(!!types[i], "Inline array cannot have empty components");
if (_tuple.isInlineArray())
{
solAssert(!!types[i], "Inline array cannot have empty components");
if ((i == 0 || inlineArrayType) && !types[i]->mobileType())
m_errorReporter.fatalTypeError(components[i]->location(), "Invalid mobile type.");
@ -1677,17 +1677,10 @@ void TypeChecker::typeCheckFunctionGeneralChecks(
{
auto const& parameterNames = _functionType->parameterNames();
// Check for expected number of named arguments
if (parameterNames.size() != argumentNames.size())
{
m_errorReporter.typeError(
_functionCall.location(),
parameterNames.size() > argumentNames.size() ?
"Some argument names are missing." :
"Too many arguments."
);
return;
}
solAssert(
parameterNames.size() == argumentNames.size(),
"Unexpected parameter length mismatch!"
);
// Check for duplicate argument names
{
@ -1971,8 +1964,8 @@ void TypeChecker::endVisit(NewExpression const& _newExpression)
_newExpression.annotation().type = make_shared<FunctionType>(
TypePointers{make_shared<IntegerType>(256)},
TypePointers{type},
strings(),
strings(),
strings(1, ""),
strings(1, ""),
FunctionType::Kind::ObjectCreation,
false,
StateMutability::Pure

View File

@ -1836,8 +1836,8 @@ MemberList::MemberMap ArrayType::nativeMembers(ContractDefinition const*) const
members.emplace_back("pop", make_shared<FunctionType>(
TypePointers{},
TypePointers{},
strings{string()},
strings{string()},
strings{},
strings{},
FunctionType::Kind::ArrayPop
));
}
@ -2191,7 +2191,7 @@ FunctionTypePointer StructType::constructorType() const
paramTypes,
TypePointers{copyForLocation(DataLocation::Memory, false)},
paramNames,
strings(),
strings(1, ""),
FunctionType::Kind::Internal
);
}
@ -2423,6 +2423,16 @@ FunctionType::FunctionType(FunctionDefinition const& _function, bool _isInternal
m_returnParameterNames.push_back(var->name());
m_returnParameterTypes.push_back(var->annotation().type);
}
solAssert(
m_parameterNames.size() == m_parameterTypes.size(),
"Parameter names list must match parameter types list!"
);
solAssert(
m_returnParameterNames.size() == m_returnParameterTypes.size(),
"Return parameter names list must match return parameter types list!"
);
}
FunctionType::FunctionType(VariableDeclaration const& _varDecl):
@ -2479,6 +2489,15 @@ FunctionType::FunctionType(VariableDeclaration const& _varDecl):
));
m_returnParameterNames.emplace_back("");
}
solAssert(
m_parameterNames.size() == m_parameterTypes.size(),
"Parameter names list must match parameter types list!"
);
solAssert(
m_returnParameterNames.size() == m_returnParameterTypes.size(),
"Return parameter names list must match return parameter types list!"
);
}
FunctionType::FunctionType(EventDefinition const& _event):
@ -2491,9 +2510,20 @@ FunctionType::FunctionType(EventDefinition const& _event):
m_parameterNames.push_back(var->name());
m_parameterTypes.push_back(var->annotation().type);
}
solAssert(
m_parameterNames.size() == m_parameterTypes.size(),
"Parameter names list must match parameter types list!"
);
solAssert(
m_returnParameterNames.size() == m_returnParameterTypes.size(),
"Return parameter names list must match return parameter types list!"
);
}
FunctionType::FunctionType(FunctionTypeName const& _typeName):
m_parameterNames(_typeName.parameterTypes().size(), ""),
m_returnParameterNames(_typeName.returnParameterTypes().size(), ""),
m_kind(_typeName.visibility() == VariableDeclaration::Visibility::External ? Kind::External : Kind::Internal),
m_stateMutability(_typeName.stateMutability())
{
@ -2519,6 +2549,15 @@ FunctionType::FunctionType(FunctionTypeName const& _typeName):
);
m_returnParameterTypes.push_back(t->annotation().type);
}
solAssert(
m_parameterNames.size() == m_parameterTypes.size(),
"Parameter names list must match parameter types list!"
);
solAssert(
m_returnParameterNames.size() == m_returnParameterTypes.size(),
"Return parameter names list must match return parameter types list!"
);
}
FunctionTypePointer FunctionType::newExpressionType(ContractDefinition const& _contract)
@ -2856,8 +2895,8 @@ MemberList::MemberMap FunctionType::nativeMembers(ContractDefinition const*) con
make_shared<FunctionType>(
parseElementaryTypeVector({"uint"}),
TypePointers{copyAndSetGasOrValue(false, true)},
strings(),
strings(),
strings(1, ""),
strings(1, ""),
Kind::SetValue,
false,
StateMutability::NonPayable,
@ -2873,8 +2912,8 @@ MemberList::MemberMap FunctionType::nativeMembers(ContractDefinition const*) con
make_shared<FunctionType>(
parseElementaryTypeVector({"uint"}),
TypePointers{copyAndSetGasOrValue(true, false)},
strings(),
strings(),
strings(1, ""),
strings(1, ""),
Kind::SetGas,
false,
StateMutability::NonPayable,
@ -3377,7 +3416,7 @@ MemberList::MemberMap MagicType::nativeMembers(ContractDefinition const*) const
TypePointers(),
TypePointers{make_shared<ArrayType>(DataLocation::Memory)},
strings{},
strings{},
strings{1, ""},
FunctionType::Kind::ABIEncode,
true,
StateMutability::Pure
@ -3386,7 +3425,7 @@ MemberList::MemberMap MagicType::nativeMembers(ContractDefinition const*) const
TypePointers(),
TypePointers{make_shared<ArrayType>(DataLocation::Memory)},
strings{},
strings{},
strings{1, ""},
FunctionType::Kind::ABIEncodePacked,
true,
StateMutability::Pure
@ -3394,8 +3433,8 @@ MemberList::MemberMap MagicType::nativeMembers(ContractDefinition const*) const
{"encodeWithSelector", make_shared<FunctionType>(
TypePointers{make_shared<FixedBytesType>(4)},
TypePointers{make_shared<ArrayType>(DataLocation::Memory)},
strings{},
strings{},
strings{1, ""},
strings{1, ""},
FunctionType::Kind::ABIEncodeWithSelector,
true,
StateMutability::Pure
@ -3403,8 +3442,8 @@ MemberList::MemberMap MagicType::nativeMembers(ContractDefinition const*) const
{"encodeWithSignature", make_shared<FunctionType>(
TypePointers{make_shared<ArrayType>(DataLocation::Memory, true)},
TypePointers{make_shared<ArrayType>(DataLocation::Memory)},
strings{},
strings{},
strings{1, ""},
strings{1, ""},
FunctionType::Kind::ABIEncodeWithSignature,
true,
StateMutability::Pure

View File

@ -1012,8 +1012,8 @@ public:
): FunctionType(
parseElementaryTypeVector(_parameterTypes),
parseElementaryTypeVector(_returnParameterTypes),
strings(),
strings(),
strings(_parameterTypes.size(), ""),
strings(_returnParameterTypes.size(), ""),
_kind,
_arbitraryParameters,
_stateMutability
@ -1050,6 +1050,14 @@ public:
m_bound(_bound),
m_declaration(_declaration)
{
solAssert(
m_parameterNames.size() == m_parameterTypes.size(),
"Parameter names list must match parameter types list!"
);
solAssert(
m_returnParameterNames.size() == m_returnParameterTypes.size(),
"Return parameter names list must match return parameter types list!"
);
solAssert(
!m_bound || !m_parameterTypes.empty(),
"Attempted construction of bound function without self type"

View File

@ -197,7 +197,7 @@ BOOST_AUTO_TEST_CASE(type_identifiers)
TypePointer keccak256fun = make_shared<FunctionType>(strings{}, strings{}, FunctionType::Kind::KECCAK256);
BOOST_CHECK_EQUAL(keccak256fun->identifier(), "t_function_keccak256_nonpayable$__$returns$__$");
FunctionType metaFun(TypePointers{keccak256fun}, TypePointers{s.type()});
FunctionType metaFun(TypePointers{keccak256fun}, TypePointers{s.type()}, strings{""}, strings{""});
BOOST_CHECK_EQUAL(metaFun.identifier(), "t_function_internal_nonpayable$_t_function_keccak256_nonpayable$__$returns$__$_$returns$_t_type$_t_struct$_Struct_$3_storage_ptr_$_$");
TypePointer m = make_shared<MappingType>(Type::fromElementaryTypeName("bytes32"), s.type());