From: Jonathan Wakely Date: Tue, 14 Feb 2017 21:17:34 +0000 (+0000) Subject: PR69321 fix any_cast(any*) for non-copyable T X-Git-Tag: releases/gcc-5.5.0~520 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ba5c2578fe438784e00e00a74fc92ca5c03fb364;p=thirdparty%2Fgcc.git PR69321 fix any_cast(any*) for non-copyable T Backport from mainline 2017-01-20 Jonathan Wakely PR libstdc++/69321 * include/experimental/any (__any_caster): Avoid instantiating manager function for types that can't be stored in any. * testsuite/experimental/any/misc/any_cast.cc: Likewise. * testsuite/experimental/any/misc/any_cast_neg.cc: Adjust dg-error. From-SVN: r245458 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index af2007343cdd..7325a2f7e544 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,14 @@ 2017-02-14 Jonathan Wakely + Backport from mainline + 2017-01-20 Jonathan Wakely + + PR libstdc++/69321 + * include/experimental/any (__any_caster): Avoid instantiating + manager function for types that can't be stored in any. + * testsuite/experimental/any/misc/any_cast.cc: Test non-copyable type. + * testsuite/experimental/any/misc/any_cast_neg.cc: Adjust dg-error. + Backport from mainline 2017-01-18 Jonathan Wakely diff --git a/libstdc++-v3/include/experimental/any b/libstdc++-v3/include/experimental/any index 30cdf54c1925..78fe39f2536e 100644 --- a/libstdc++-v3/include/experimental/any +++ b/libstdc++-v3/include/experimental/any @@ -236,14 +236,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Storage _M_storage; template - friend void* __any_caster(const any* __any) - { - if (__any->_M_manager != &_Manager>::_S_manage) - return nullptr; - _Arg __arg; - __any->_M_manager(_Op_access, __any, &__arg); - return __arg._M_obj; - } + friend void* __any_caster(const any* __any); // Manage in-place contained object. template @@ -347,6 +340,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } // @} + template + void* __any_caster(const any* __any) + { + struct _None { }; + using _Up = decay_t<_Tp>; + using _Vp = conditional_t::value, _Up, _None>; + if (__any->_M_manager != &any::_Manager<_Vp>::_S_manage) + return nullptr; + any::_Arg __arg; + __any->_M_manager(any::_Op_access, __any, &__arg); + return __arg._M_obj; + } + /** * @brief Access the contained object. * diff --git a/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc b/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc index f5d1d7723b19..ce4424ee0c39 100644 --- a/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc +++ b/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc @@ -77,8 +77,21 @@ void test02() } } +void test04() +{ + // PR libstdc++/69321 + struct noncopyable { + noncopyable(noncopyable const&) = delete; + }; + + any a; + auto p = any_cast(&a); + VERIFY( p == nullptr ); +} + int main() { test01(); test02(); + test04(); } diff --git a/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc b/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc index 28388f68b0f3..7bc818a36b51 100644 --- a/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc +++ b/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc @@ -26,5 +26,5 @@ void test01() using std::experimental::any_cast; const any y(1); - any_cast(y); // { dg-error "qualifiers" "" { target { *-*-* } } 311 } + any_cast(y); // { dg-error "qualifiers" "" { target { *-*-* } } 304 } }