Merge pull request #4378 from ethereum/noBaseWithoutArguments

[BREAKING] Disallow calling base constructors without arguments.
This commit is contained in:
Alex Beregszaszi 2018-08-01 13:18:37 +01:00 committed by GitHub
commit ce99a5ce7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 18 additions and 18 deletions

View File

@ -39,6 +39,7 @@ Breaking Changes:
* Type Checker: Disallow values for constants that are not compile-time constants. This was already the case in the experimental 0.5.0 mode.
* Type Checker: Disallow arithmetic operations for boolean variables.
* Type Checker: Disallow tight packing of literals. This was already the case in the experimental 0.5.0 mode.
* Type Checker: Disallow calling base constructors without parentheses. This was already the case in the experimental 0.5.0 mode.
* Type Checker: Disallow conversions between ``bytesX`` and ``uintY`` of different size.
* Type Checker: Disallow conversions between unrelated contract types. Explicit conversion via ``address`` can still achieve it.
* Type Checker: Disallow empty tuple components. This was partly already the case in the experimental 0.5.0 mode.

View File

@ -279,8 +279,6 @@ void TypeChecker::checkContractAbstractFunctions(ContractDefinition const& _cont
void TypeChecker::checkContractBaseConstructorArguments(ContractDefinition const& _contract)
{
bool const v050 = _contract.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050);
vector<ContractDefinition const*> const& bases = _contract.annotation().linearizedBaseContracts;
// Determine the arguments that are used for the base constructors.
@ -288,27 +286,19 @@ void TypeChecker::checkContractBaseConstructorArguments(ContractDefinition const
{
if (FunctionDefinition const* constructor = contract->constructor())
for (auto const& modifier: constructor->modifiers())
{
auto baseContract = dynamic_cast<ContractDefinition const*>(&dereference(*modifier->name()));
if (modifier->arguments())
if (auto baseContract = dynamic_cast<ContractDefinition const*>(&dereference(*modifier->name())))
{
if (baseContract && baseContract->constructor())
annotateBaseConstructorArguments(_contract, baseContract->constructor(), modifier.get());
}
else
{
if (v050)
if (modifier->arguments())
{
if (baseContract->constructor())
annotateBaseConstructorArguments(_contract, baseContract->constructor(), modifier.get());
}
else
m_errorReporter.declarationError(
modifier->location(),
"Modifier-style base constructor call without arguments."
);
else
m_errorReporter.warning(
modifier->location(),
"Modifier-style base constructor call without arguments."
);
}
}
for (ASTPointer<InheritanceSpecifier> const& base: contract->baseContracts())
{

View File

@ -1,4 +1,4 @@
contract A { constructor() public { } }
contract B is A { constructor() A public { } }
// ----
// Warning: (72-73): Modifier-style base constructor call without arguments.
// DeclarationError: (72-73): Modifier-style base constructor call without arguments.

View File

@ -0,0 +1,9 @@
// This generated an invalid warning on m1 in some compiler versions.
contract A {
constructor() m1 public { }
modifier m1 { _; }
}
contract B is A {
modifier m2 { _; }
constructor() A() m1 m2 public { }
}