mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Allow duplicated constructor calls, if no arguments; support for multiple inheritance; backwards compatibility.
# tmp
This commit is contained in:
parent
4e037281ac
commit
b8fdb666e2
@ -9,6 +9,7 @@ Features:
|
|||||||
* Optimizer: Remove useless ``SWAP1`` instruction preceding a commutative instruction (such as ``ADD``, ``MUL``, etc).
|
* Optimizer: Remove useless ``SWAP1`` instruction preceding a commutative instruction (such as ``ADD``, ``MUL``, etc).
|
||||||
* Optimizer: Replace comparison operators (``LT``, ``GT``, etc) with opposites if preceded by ``SWAP1``, e.g. ``SWAP1 LT`` is replaced with ``GT``.
|
* Optimizer: Replace comparison operators (``LT``, ``GT``, etc) with opposites if preceded by ``SWAP1``, e.g. ``SWAP1 LT`` is replaced with ``GT``.
|
||||||
* Optimizer: Optimize across ``mload`` if ``msize()`` is not used.
|
* Optimizer: Optimize across ``mload`` if ``msize()`` is not used.
|
||||||
|
* Static Analyzer: Error on duplicated super constructor calls as experimental 0.5.0 feature.
|
||||||
* Syntax Checker: Issue warning for empty structs (or error as experimental 0.5.0 feature).
|
* Syntax Checker: Issue warning for empty structs (or error as experimental 0.5.0 feature).
|
||||||
* General: Introduce new constructor syntax using the ``constructor`` keyword as experimental 0.5.0 feature.
|
* General: Introduce new constructor syntax using the ``constructor`` keyword as experimental 0.5.0 feature.
|
||||||
* Inheritance: Error when using empty parenthesis for base class constructors that require arguments as experimental 0.5.0 feature.
|
* Inheritance: Error when using empty parenthesis for base class constructors that require arguments as experimental 0.5.0 feature.
|
||||||
@ -28,7 +29,6 @@ Bugfixes:
|
|||||||
* Type System: Make external library functions accessible.
|
* Type System: Make external library functions accessible.
|
||||||
* Type System: Prevent encoding of weird types.
|
* Type System: Prevent encoding of weird types.
|
||||||
* Static Analyzer: Fix non-deterministic order of unused variable warnings.
|
* Static Analyzer: Fix non-deterministic order of unused variable warnings.
|
||||||
* Static Analyzer: Error on duplicated super constructor calls.
|
|
||||||
|
|
||||||
### 0.4.21 (2018-03-07)
|
### 0.4.21 (2018-03-07)
|
||||||
|
|
||||||
|
@ -90,33 +90,43 @@ void StaticAnalyzer::endVisit(FunctionDefinition const&)
|
|||||||
m_localVarUseCount.clear();
|
m_localVarUseCount.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool modifierOverridesInheritanceSpecifier(
|
|
||||||
ContractDefinition const* _contract,
|
|
||||||
ModifierInvocation const& _modifier,
|
|
||||||
InheritanceSpecifier const& _specifier
|
|
||||||
)
|
|
||||||
{
|
|
||||||
auto parent = _specifier.name().annotation().referencedDeclaration;
|
|
||||||
return _contract == parent && (!_specifier.arguments().empty() || _modifier.arguments().empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StaticAnalyzer::visit(ModifierInvocation const& _modifier)
|
bool StaticAnalyzer::visit(ModifierInvocation const& _modifier)
|
||||||
{
|
{
|
||||||
if (!m_constructor)
|
if (!m_constructor)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (auto contract = dynamic_cast<ContractDefinition const*>(_modifier.name()->annotation().referencedDeclaration))
|
bool const v050 = m_currentContract->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050);
|
||||||
for (auto const& specifier: m_currentContract->baseContracts())
|
|
||||||
if (modifierOverridesInheritanceSpecifier(contract, _modifier, *specifier))
|
|
||||||
{
|
|
||||||
SecondarySourceLocation ssl;
|
|
||||||
ssl.append("Overriden constructor call is here:", specifier->location());
|
|
||||||
|
|
||||||
m_errorReporter.declarationError(
|
if (auto contract = dynamic_cast<ContractDefinition const*>(_modifier.name()->annotation().referencedDeclaration))
|
||||||
_modifier.location(),
|
for (auto const& base: m_currentContract->annotation().linearizedBaseContracts)
|
||||||
ssl,
|
for (auto const& specifier: base->baseContracts())
|
||||||
"Duplicated super constructor call."
|
{
|
||||||
);
|
Declaration const* parent = specifier->name().annotation().referencedDeclaration;
|
||||||
|
if (contract == parent && !specifier->arguments().empty())
|
||||||
|
{
|
||||||
|
if (v050)
|
||||||
|
{
|
||||||
|
SecondarySourceLocation ssl;
|
||||||
|
ssl.append("Second constructor call is here:", specifier->location());
|
||||||
|
|
||||||
|
m_errorReporter.declarationError(
|
||||||
|
_modifier.location(),
|
||||||
|
ssl,
|
||||||
|
"Duplicated super constructor call."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SecondarySourceLocation ssl;
|
||||||
|
ssl.append("Overridden constructor call is here:", specifier->location());
|
||||||
|
|
||||||
|
m_errorReporter.warning(
|
||||||
|
_modifier.location(),
|
||||||
|
"Duplicated super constructor calls are deprecated.",
|
||||||
|
ssl
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
contract A { constructor() public { } }
|
||||||
|
contract B1 is A { constructor() A() public { } }
|
||||||
|
contract B2 is A { constructor() A public { } }
|
@ -0,0 +1,9 @@
|
|||||||
|
contract Base {
|
||||||
|
constructor(uint) public { }
|
||||||
|
}
|
||||||
|
contract Base1 is Base(3) {}
|
||||||
|
contract Derived is Base, Base1 {
|
||||||
|
constructor(uint i) Base(i) public {}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// Warning: Duplicated super constructor calls are deprecated.
|
@ -0,0 +1,5 @@
|
|||||||
|
contract A { constructor(uint) public { } }
|
||||||
|
contract B is A(2) { constructor() public { } }
|
||||||
|
contract C is B { constructor() A(3) public { } }
|
||||||
|
// ----
|
||||||
|
// Warning: Duplicated super constructor calls are deprecated.
|
@ -0,0 +1,7 @@
|
|||||||
|
pragma experimental "v0.5.0";
|
||||||
|
|
||||||
|
contract A { constructor(uint) public { } }
|
||||||
|
contract B is A(2) { constructor() public { } }
|
||||||
|
contract C is B { constructor() A(3) public { } }
|
||||||
|
// ----
|
||||||
|
// DeclarationError: Duplicated super constructor call.
|
@ -1,4 +1,4 @@
|
|||||||
contract A { constructor(uint) public { } }
|
contract A { constructor(uint) public { } }
|
||||||
contract B is A(2) { constructor() A(3) public { } }
|
contract B is A(2) { constructor() A(3) public { } }
|
||||||
// ----
|
// ----
|
||||||
// DeclarationError: Duplicated super constructor call.
|
// Warning: Duplicated super constructor calls are deprecated.
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
pragma experimental "v0.5.0";
|
||||||
|
|
||||||
|
contract A { constructor(uint) public { } }
|
||||||
|
contract B is A(2) { constructor() A(3) public { } }
|
||||||
|
// ----
|
||||||
|
// DeclarationError: Duplicated super constructor call.
|
@ -1,4 +0,0 @@
|
|||||||
contract A { constructor() public { } }
|
|
||||||
contract B is A { constructor() A() public { } }
|
|
||||||
// ----
|
|
||||||
// DeclarationError: Duplicated super constructor call.
|
|
@ -0,0 +1,7 @@
|
|||||||
|
contract C { constructor(uint) public {} }
|
||||||
|
contract A is C(2) {}
|
||||||
|
contract B is C(2) {}
|
||||||
|
contract D is A, B { constructor() C(3) public {} }
|
||||||
|
// ----
|
||||||
|
// Warning: Duplicated super constructor calls are deprecated.
|
||||||
|
// Warning: Duplicated super constructor calls are deprecated.
|
Loading…
Reference in New Issue
Block a user