diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2017-01-20 01:22:54 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2017-01-20 01:22:54 +0000 |
commit | 38a9e5a6c07d84274bc5d345b947d1c13351d590 (patch) | |
tree | 3d61b326d740e796dfbb370ca1db3de644acf9f2 | |
parent | 01334be4a08330081eb74181faec5fbb4c30bcda (diff) | |
download | gcc-38a9e5a6c07d84274bc5d345b947d1c13351d590.zip gcc-38a9e5a6c07d84274bc5d345b947d1c13351d590.tar.gz gcc-38a9e5a6c07d84274bc5d345b947d1c13351d590.tar.bz2 |
PR69321 fix any_cast<T>(any*) for non-copyable T
PR libstdc++/69321
* include/experimental/any (__any_caster): Avoid instantiating
manager function for types that can't be stored in any.
* include/std/any (__any_caster): Likewise.
* testsuite/20_util/any/misc/any_cast.cc: Test non-copyable type.
* testsuite/experimental/any/misc/any_cast.cc: Likewise.
From-SVN: r244678
-rw-r--r-- | libstdc++-v3/ChangeLog | 7 | ||||
-rw-r--r-- | libstdc++-v3/include/experimental/any | 5 | ||||
-rw-r--r-- | libstdc++-v3/include/std/any | 15 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/any/misc/any_cast.cc | 13 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc | 13 |
5 files changed, 47 insertions, 6 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 4cb727c..b4be6e5 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,12 @@ 2017-01-20 Jonathan Wakely <jwakely@redhat.com> + PR libstdc++/69321 + * include/experimental/any (__any_caster): Avoid instantiating + manager function for types that can't be stored in any. + * include/std/any (__any_caster): Likewise. + * testsuite/20_util/any/misc/any_cast.cc: Test non-copyable type. + * testsuite/experimental/any/misc/any_cast.cc: Likewise. + PR libstdc++/64903 * include/bits/stl_algo.h (is_partitioned): Use increment instead of std::advance. diff --git a/libstdc++-v3/include/experimental/any b/libstdc++-v3/include/experimental/any index d9f06cd..36c0680 100644 --- a/libstdc++-v3/include/experimental/any +++ b/libstdc++-v3/include/experimental/any @@ -415,7 +415,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> void* __any_caster(const any* __any) { - if (__any->_M_manager != &any::_Manager<decay_t<_Tp>>::_S_manage) + struct _None { }; + using _Up = decay_t<_Tp>; + using _Vp = conditional_t<is_copy_constructible<_Up>::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); diff --git a/libstdc++-v3/include/std/any b/libstdc++-v3/include/std/any index 8a60075..e807617 100644 --- a/libstdc++-v3/include/std/any +++ b/libstdc++-v3/include/std/any @@ -511,11 +511,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> void* __any_caster(const any* __any) { - if (__any->_M_manager != &any::_Manager<decay_t<_Tp>>::_S_manage) - return nullptr; - any::_Arg __arg; - __any->_M_manager(any::_Op_access, __any, &__arg); - return __arg._M_obj; + if constexpr (is_copy_constructible_v<decay_t<_Tp>>) + { + if (__any->_M_manager == &any::_Manager<decay_t<_Tp>>::_S_manage) + { + any::_Arg __arg; + __any->_M_manager(any::_Op_access, __any, &__arg); + return __arg._M_obj; + } + } + return nullptr; } /** diff --git a/libstdc++-v3/testsuite/20_util/any/misc/any_cast.cc b/libstdc++-v3/testsuite/20_util/any/misc/any_cast.cc index 559e4e9..72581e6 100644 --- a/libstdc++-v3/testsuite/20_util/any/misc/any_cast.cc +++ b/libstdc++-v3/testsuite/20_util/any/misc/any_cast.cc @@ -118,10 +118,23 @@ void test04() ExplicitCopy ec2{any_cast<ExplicitCopy>(std::move(x))}; } +void test05() +{ + // PR libstdc++/69321 + struct noncopyable { + noncopyable(noncopyable const&) = delete; + }; + + any a; + auto p = any_cast<noncopyable>(&a); + VERIFY( p == nullptr ); +} + int main() { test01(); test02(); test03(); test04(); + test05(); } diff --git a/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc b/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc index b6cc114..62ab1b3 100644 --- a/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc +++ b/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc @@ -105,9 +105,22 @@ void test03() MoveDeleted&& md3 = any_cast<MoveDeleted&&>(any(std::move(md))); } +void test04() +{ + // PR libstdc++/69321 + struct noncopyable { + noncopyable(noncopyable const&) = delete; + }; + + any a; + auto p = any_cast<noncopyable>(&a); + VERIFY( p == nullptr ); +} + int main() { test01(); test02(); test03(); + test04(); } |