aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Kirchner <daniel@ekpyron.org>2018-04-04 18:28:22 +0800
committerDaniel Kirchner <daniel@ekpyron.org>2018-04-09 21:26:05 +0800
commitb8fdb666e235bb6b19f11dba7740227026111598 (patch)
tree052d6a730b300e6c976759ac993d879153082c08
parent4e037281acaf74c907f68e6227d6aa1b8847c78d (diff)
downloaddexon-solidity-b8fdb666e235bb6b19f11dba7740227026111598.tar.gz
dexon-solidity-b8fdb666e235bb6b19f11dba7740227026111598.tar.zst
dexon-solidity-b8fdb666e235bb6b19f11dba7740227026111598.zip
Allow duplicated constructor calls, if no arguments; support for multiple inheritance; backwards compatibility.
# tmp
-rw-r--r--Changelog.md2
-rw-r--r--libsolidity/analysis/StaticAnalyzer.cpp50
-rw-r--r--test/libsolidity/syntaxTests/inheritance/allow_empty_duplicated_super_constructor_call.sol3
-rw-r--r--test/libsolidity/syntaxTests/inheritance/base_arguments_multiple_inheritance.sol9
-rw-r--r--test/libsolidity/syntaxTests/inheritance/duplicated_ancestor_constructor_call.sol5
-rw-r--r--test/libsolidity/syntaxTests/inheritance/duplicated_ancestor_constructor_call_V050.sol7
-rw-r--r--test/libsolidity/syntaxTests/inheritance/duplicated_super_constructor_call.sol2
-rw-r--r--test/libsolidity/syntaxTests/inheritance/duplicated_super_constructor_call_V050.sol6
-rw-r--r--test/libsolidity/syntaxTests/inheritance/duplicated_super_constructor_call_empty.sol4
-rw-r--r--test/libsolidity/syntaxTests/inheritance/duplicated_super_constructor_call_multi.sol7
10 files changed, 69 insertions, 26 deletions
diff --git a/Changelog.md b/Changelog.md
index 94703f7d..3b8cba1d 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -9,6 +9,7 @@ Features:
* 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: 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).
* 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.
@@ -28,7 +29,6 @@ Bugfixes:
* Type System: Make external library functions accessible.
* Type System: Prevent encoding of weird types.
* Static Analyzer: Fix non-deterministic order of unused variable warnings.
- * Static Analyzer: Error on duplicated super constructor calls.
### 0.4.21 (2018-03-07)
diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp
index 6c70ba6b..700c8a71 100644
--- a/libsolidity/analysis/StaticAnalyzer.cpp
+++ b/libsolidity/analysis/StaticAnalyzer.cpp
@@ -90,33 +90,43 @@ void StaticAnalyzer::endVisit(FunctionDefinition const&)
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)
{
if (!m_constructor)
return true;
+ bool const v050 = m_currentContract->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050);
+
if (auto contract = dynamic_cast<ContractDefinition const*>(_modifier.name()->annotation().referencedDeclaration))
- for (auto const& specifier: m_currentContract->baseContracts())
- if (modifierOverridesInheritanceSpecifier(contract, _modifier, *specifier))
+ for (auto const& base: m_currentContract->annotation().linearizedBaseContracts)
+ for (auto const& specifier: base->baseContracts())
{
- SecondarySourceLocation ssl;
- ssl.append("Overriden constructor call is here:", specifier->location());
-
- m_errorReporter.declarationError(
- _modifier.location(),
- ssl,
- "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;
diff --git a/test/libsolidity/syntaxTests/inheritance/allow_empty_duplicated_super_constructor_call.sol b/test/libsolidity/syntaxTests/inheritance/allow_empty_duplicated_super_constructor_call.sol
new file mode 100644
index 00000000..1f580b1d
--- /dev/null
+++ b/test/libsolidity/syntaxTests/inheritance/allow_empty_duplicated_super_constructor_call.sol
@@ -0,0 +1,3 @@
+contract A { constructor() public { } }
+contract B1 is A { constructor() A() public { } }
+contract B2 is A { constructor() A public { } }
diff --git a/test/libsolidity/syntaxTests/inheritance/base_arguments_multiple_inheritance.sol b/test/libsolidity/syntaxTests/inheritance/base_arguments_multiple_inheritance.sol
new file mode 100644
index 00000000..f63d0f02
--- /dev/null
+++ b/test/libsolidity/syntaxTests/inheritance/base_arguments_multiple_inheritance.sol
@@ -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.
diff --git a/test/libsolidity/syntaxTests/inheritance/duplicated_ancestor_constructor_call.sol b/test/libsolidity/syntaxTests/inheritance/duplicated_ancestor_constructor_call.sol
new file mode 100644
index 00000000..97f3f8ff
--- /dev/null
+++ b/test/libsolidity/syntaxTests/inheritance/duplicated_ancestor_constructor_call.sol
@@ -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.
diff --git a/test/libsolidity/syntaxTests/inheritance/duplicated_ancestor_constructor_call_V050.sol b/test/libsolidity/syntaxTests/inheritance/duplicated_ancestor_constructor_call_V050.sol
new file mode 100644
index 00000000..933c9087
--- /dev/null
+++ b/test/libsolidity/syntaxTests/inheritance/duplicated_ancestor_constructor_call_V050.sol
@@ -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.
diff --git a/test/libsolidity/syntaxTests/inheritance/duplicated_super_constructor_call.sol b/test/libsolidity/syntaxTests/inheritance/duplicated_super_constructor_call.sol
index 95df1040..876b07ea 100644
--- a/test/libsolidity/syntaxTests/inheritance/duplicated_super_constructor_call.sol
+++ b/test/libsolidity/syntaxTests/inheritance/duplicated_super_constructor_call.sol
@@ -1,4 +1,4 @@
contract A { constructor(uint) public { } }
contract B is A(2) { constructor() A(3) public { } }
// ----
-// DeclarationError: Duplicated super constructor call.
+// Warning: Duplicated super constructor calls are deprecated.
diff --git a/test/libsolidity/syntaxTests/inheritance/duplicated_super_constructor_call_V050.sol b/test/libsolidity/syntaxTests/inheritance/duplicated_super_constructor_call_V050.sol
new file mode 100644
index 00000000..31a363fd
--- /dev/null
+++ b/test/libsolidity/syntaxTests/inheritance/duplicated_super_constructor_call_V050.sol
@@ -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.
diff --git a/test/libsolidity/syntaxTests/inheritance/duplicated_super_constructor_call_empty.sol b/test/libsolidity/syntaxTests/inheritance/duplicated_super_constructor_call_empty.sol
deleted file mode 100644
index f8024ad6..00000000
--- a/test/libsolidity/syntaxTests/inheritance/duplicated_super_constructor_call_empty.sol
+++ /dev/null
@@ -1,4 +0,0 @@
-contract A { constructor() public { } }
-contract B is A { constructor() A() public { } }
-// ----
-// DeclarationError: Duplicated super constructor call.
diff --git a/test/libsolidity/syntaxTests/inheritance/duplicated_super_constructor_call_multi.sol b/test/libsolidity/syntaxTests/inheritance/duplicated_super_constructor_call_multi.sol
new file mode 100644
index 00000000..caed18eb
--- /dev/null
+++ b/test/libsolidity/syntaxTests/inheritance/duplicated_super_constructor_call_multi.sol
@@ -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.