Force contracts with constructors with internal parameters abstract.

This commit is contained in:
chriseth 2020-06-18 17:33:36 +02:00
parent da36400576
commit f6232393ef

View File

@ -340,35 +340,62 @@ bool TypeChecker::visit(FunctionDefinition const& _function)
if (_function.isOrdinary() && !_function.isPartOfExternalInterface())
m_errorReporter.typeError(5587_error, _function.location(), "Internal functions cannot be payable.");
}
auto checkArgumentAndReturnParameter = [&](VariableDeclaration const& var) {
if (type(var)->containsNestedMapping())
if (var.referenceLocation() == VariableDeclaration::Location::Storage)
vector<VariableDeclaration const*> internalParametersInConstructor;
auto checkArgumentAndReturnParameter = [&](VariableDeclaration const& _var) {
if (type(_var)->containsNestedMapping())
if (_var.referenceLocation() == VariableDeclaration::Location::Storage)
solAssert(
_function.libraryFunction() || !_function.isPublic(),
_function.libraryFunction() || _function.isConstructor() || !_function.isPublic(),
"Mapping types for parameters or return variables "
"can only be used in internal or library functions."
);
if (_function.isPublic())
bool functionIsExternallyVisible =
(!_function.isConstructor() && _function.isPublic()) ||
(_function.isConstructor() && !m_currentContract->abstract());
if (
_function.isConstructor() &&
_var.referenceLocation() == VariableDeclaration::Location::Storage &&
!m_currentContract->abstract()
)
m_errorReporter.typeError(
3644_error,
_var.location(),
"This parameter has a type that can only be used internally. "
"You can make the contract abstract to avoid this problem."
);
else if (functionIsExternallyVisible)
{
auto iType = type(var)->interfaceType(_function.libraryFunction());
auto iType = type(_var)->interfaceType(_function.libraryFunction());
if (!iType)
{
solAssert(!iType.message().empty(), "Expected detailed error message!");
m_errorReporter.typeError(4103_error, var.location(), iType.message());
string message = iType.message();
solAssert(!message.empty(), "Expected detailed error message!");
if (_function.isConstructor())
message += " You can make the contract abstract to avoid this problem.";
m_errorReporter.typeError(4103_error, _var.location(), message);
}
else if (
!experimentalFeatureActive(ExperimentalFeature::ABIEncoderV2) &&
!typeSupportedByOldABIEncoder(*type(_var), _function.libraryFunction())
)
{
string message =
"This type is only supported in ABIEncoderV2. "
"Use \"pragma experimental ABIEncoderV2;\" to enable the feature.";
if (_function.isConstructor())
message +=
" Alternatively, make the contract abstract and supply the "
"constructor arguments from a derived contract.";
m_errorReporter.typeError(
4957_error,
_var.location(),
message
);
}
}
if (
_function.isPublic() &&
!experimentalFeatureActive(ExperimentalFeature::ABIEncoderV2) &&
!typeSupportedByOldABIEncoder(*type(var), _function.libraryFunction())
)
m_errorReporter.typeError(
4957_error,
var.location(),
"This type is only supported in ABIEncoderV2. "
"Use \"pragma experimental ABIEncoderV2;\" to enable the feature."
);
};
for (ASTPointer<VariableDeclaration> const& var: _function.parameters())
{
@ -380,6 +407,7 @@ bool TypeChecker::visit(FunctionDefinition const& _function)
checkArgumentAndReturnParameter(*var);
var->accept(*this);
}
set<Declaration const*> modifiers;
for (ASTPointer<ModifierInvocation> const& modifier: _function.modifiers())
{