aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2017-03-22 01:41:53 +0800
committerGitHub <noreply@github.com>2017-03-22 01:41:53 +0800
commitd626876310c6c4d134b97b847d199dd78d3c5bea (patch)
tree2c3c288879eeeb77877c51a2cef23ce339bcaadd
parent6fb27dee635748110a27654a5a2c322d865b8578 (diff)
parentd8aacd5a404f7fedaec269f0d30284a8a7fc6ffc (diff)
downloaddexon-solidity-d626876310c6c4d134b97b847d199dd78d3c5bea.tar
dexon-solidity-d626876310c6c4d134b97b847d199dd78d3c5bea.tar.gz
dexon-solidity-d626876310c6c4d134b97b847d199dd78d3c5bea.tar.bz2
dexon-solidity-d626876310c6c4d134b97b847d199dd78d3c5bea.tar.lz
dexon-solidity-d626876310c6c4d134b97b847d199dd78d3c5bea.tar.xz
dexon-solidity-d626876310c6c4d134b97b847d199dd78d3c5bea.tar.zst
dexon-solidity-d626876310c6c4d134b97b847d199dd78d3c5bea.zip
Merge pull request #1811 from ethereum/unimplementedConstructors
Contract inheriting from base with unimplemented constructor is abstract.
-rw-r--r--Changelog.md3
-rw-r--r--libsolidity/analysis/TypeChecker.cpp10
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp7
3 files changed, 19 insertions, 1 deletions
diff --git a/Changelog.md b/Changelog.md
index 2a267fd7..5c991032 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -3,6 +3,9 @@
Features:
* Support ``interface`` contracts.
+Bugfixes:
+ * Type system: Contract inheriting from base with unimplemented constructor should be abstract.
+
### 0.4.10 (2017-03-15)
Features:
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp
index 30e84f11..dc04404d 100644
--- a/libsolidity/analysis/TypeChecker.cpp
+++ b/libsolidity/analysis/TypeChecker.cpp
@@ -187,13 +187,20 @@ void TypeChecker::checkContractAbstractFunctions(ContractDefinition const& _cont
using FunTypeAndFlag = std::pair<FunctionTypePointer, bool>;
map<string, vector<FunTypeAndFlag>> functions;
+ bool allBaseConstructorsImplemented = true;
// Search from base to derived
for (ContractDefinition const* contract: boost::adaptors::reverse(_contract.annotation().linearizedBaseContracts))
for (FunctionDefinition const* function: contract->definedFunctions())
{
// Take constructors out of overload hierarchy
if (function->isConstructor())
+ {
+ if (!function->isImplemented())
+ // Base contract's constructor is not fully implemented, no way to get
+ // out of this.
+ allBaseConstructorsImplemented = false;
continue;
+ }
auto& overloads = functions[function->name()];
FunctionTypePointer funType = make_shared<FunctionType>(*function);
auto it = find_if(overloads.begin(), overloads.end(), [&](FunTypeAndFlag const& _funAndFlag)
@@ -211,6 +218,9 @@ void TypeChecker::checkContractAbstractFunctions(ContractDefinition const& _cont
it->second = true;
}
+ if (!allBaseConstructorsImplemented)
+ _contract.annotation().isFullyImplemented = false;
+
// Set to not fully implemented if at least one flag is false.
for (auto const& it: functions)
for (auto const& funAndFlag: it.second)
diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index c002fd3e..1388f01b 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -624,7 +624,12 @@ BOOST_AUTO_TEST_CASE(abstract_contract_constructor_args_optional)
function foo() {}
}
)";
- ETH_TEST_REQUIRE_NO_THROW(parseAndAnalyse(text), "Parsing and name resolving failed");
+ ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name resolving failed");
+ std::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes();
+ BOOST_CHECK_EQUAL(nodes.size(), 4);
+ ContractDefinition* derived = dynamic_cast<ContractDefinition*>(nodes[3].get());
+ BOOST_REQUIRE(derived);
+ BOOST_CHECK(!derived->annotation().isFullyImplemented);
}
BOOST_AUTO_TEST_CASE(abstract_contract_constructor_args_not_provided)