From 0019c53f5cc0edef34535d233150726318895057 Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 19 Jan 2015 23:34:49 +0100 Subject: [PATCH] Implicit conversion from derived to base. --- libsolidity/Types.cpp | 9 ++++++++- test/SolidityNameAndTypeResolution.cpp | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 94fd57501..c6d8b62fc 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -431,12 +431,19 @@ bool ContractType::isImplicitlyConvertibleTo(Type const& _convertTo) const return true; if (_convertTo.getCategory() == Category::INTEGER) return dynamic_cast(_convertTo).isAddress(); + if (_convertTo.getCategory() == Category::CONTRACT) + { + auto const& bases = getContractDefinition().getLinearizedBaseContracts(); + return find(bases.begin(), bases.end(), + &dynamic_cast(_convertTo).getContractDefinition()) != bases.end(); + } return false; } bool ContractType::isExplicitlyConvertibleTo(Type const& _convertTo) const { - return isImplicitlyConvertibleTo(_convertTo) || _convertTo.getCategory() == Category::INTEGER; + return isImplicitlyConvertibleTo(_convertTo) || _convertTo.getCategory() == Category::INTEGER || + _convertTo.getCategory() == Category::CONTRACT; } TypePointer ContractType::unaryOperatorResult(Token::Value _operator) const diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index c0ebb0eda..6c8fd1b1c 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -469,6 +469,27 @@ BOOST_AUTO_TEST_CASE(base_constructor_arguments_override) BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); } +BOOST_AUTO_TEST_CASE(implicit_derived_to_base_conversion) +{ + char const* text = R"( + contract A { } + contract B is A { + function f() { A a = B(1); } + } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} +BOOST_AUTO_TEST_CASE(implicit_base_to_derived_conversion) +{ + char const* text = R"( + contract A { } + contract B is A { + function f() { B b = A(1); } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() }