On 19/10/16 21:13 +0100, Jonathan Wakely wrote:
The standard says we have to enable shared_from_this for types with an accessible and unambiguous std::enable_shared_from_this base class, and we should be able to do that even if the class also has an experimental::enable_shared_from_this base class. Now we can.
This adds some more checks for that case. Tested x86_64-linux, committed to trunk.
commit ad6e844e7d0a30a5cb53044d6147f291f9d70378 Author: Jonathan Wakely <jwak...@redhat.com> Date: Thu Oct 20 01:00:16 2016 +0100 Add more tests for enable_shared_from_this ambiguities * testsuite/20_util/enable_shared_from_this/56383.cc: Add tests for additional ambiguous cases. diff --git a/libstdc++-v3/testsuite/20_util/enable_shared_from_this/56383.cc b/libstdc++-v3/testsuite/20_util/enable_shared_from_this/56383.cc index fb3fa69..9220eaf 100644 --- a/libstdc++-v3/testsuite/20_util/enable_shared_from_this/56383.cc +++ b/libstdc++-v3/testsuite/20_util/enable_shared_from_this/56383.cc @@ -20,37 +20,66 @@ #include <memory> #include <testsuite_hooks.h> -struct A : std::enable_shared_from_this<A> +template<typename T> +bool not_enabled(T& t) { - void* a() { return shared_from_this().get(); } -}; +#if __cpp_lib_enable_shared_from_this >= 201603 + return t.weak_from_this().expired(); +#else + try { + t.shared_from_this(); + return false; + } catch (const std::bad_weak_ptr&) { + return true; + } +#endif +} -struct B : std::enable_shared_from_this<B> -{ -}; - -struct D : A, B -{ -}; +struct A : std::enable_shared_from_this<A> { }; +struct B : std::enable_shared_from_this<B> { }; +struct D : A, B { }; void test01() { - bool test = false; - auto d = std::make_shared<D>(); - try - { - d->a(); - } - catch (const std::bad_weak_ptr&) - { - test = true; - } - VERIFY(test); + VERIFY( not_enabled( static_cast<A&>(*d) ) ); + VERIFY( not_enabled( static_cast<const A&>(*d) ) ); + VERIFY( not_enabled( static_cast<B&>(*d) ) ); + VERIFY( not_enabled( static_cast<const B&>(*d) ) ); +} + +struct E : std::__enable_shared_from_this<E> { }; +struct F : std::__enable_shared_from_this<F> { }; +struct G : E, F { }; + +void test02() +{ + auto g = std::make_shared<G>(); + VERIFY( not_enabled( static_cast<E&>(*g) ) ); + VERIFY( not_enabled( static_cast<const E&>(*g) ) ); + VERIFY( not_enabled( static_cast<F&>(*g) ) ); + VERIFY( not_enabled( static_cast<const F&>(*g) ) ); +} + +struct H : D, G { }; + +void test03() +{ + auto h = std::make_shared<H>(); + VERIFY( not_enabled( static_cast<A&>(*h) ) ); + VERIFY( not_enabled( static_cast<const A&>(*h) ) ); + VERIFY( not_enabled( static_cast<B&>(*h) ) ); + VERIFY( not_enabled( static_cast<const B&>(*h) ) ); + VERIFY( not_enabled( static_cast<E&>(*h) ) ); + VERIFY( not_enabled( static_cast<const E&>(*h) ) ); + VERIFY( not_enabled( static_cast<F&>(*h) ) ); + VERIFY( not_enabled( static_cast<const F&>(*h) ) ); } int main() { test01(); + test02(); + test03(); }