mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Force contracts with constructors with internal parameters abstract.
This commit is contained in:
parent
da36400576
commit
f6232393ef
@ -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);
|
||||
}
|
||||
}
|
||||
if (
|
||||
_function.isPublic() &&
|
||||
else if (
|
||||
!experimentalFeatureActive(ExperimentalFeature::ABIEncoderV2) &&
|
||||
!typeSupportedByOldABIEncoder(*type(var), _function.libraryFunction())
|
||||
!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(),
|
||||
"This type is only supported in ABIEncoderV2. "
|
||||
"Use \"pragma experimental ABIEncoderV2;\" to enable the feature."
|
||||
_var.location(),
|
||||
message
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
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())
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user