diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2017-02-14 20:08:04 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2017-02-14 20:08:04 +0000 |
commit | 58868f8e89636148754e0e315874f5993b3dcd5b (patch) | |
tree | 247436e9f50cf36b2f761d3d9f5ababfe6a23adf /libstdc++-v3 | |
parent | 059f7e17cb8e2e314ac635016b58015f18d283e2 (diff) | |
download | gcc-58868f8e89636148754e0e315874f5993b3dcd5b.tar.gz |
PR69321 fix any_cast<T>(any*) for non-copyable T
Backport from mainline
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.
* testsuite/experimental/any/misc/any_cast.cc: Likewise.
From-SVN: r245451
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 8 | ||||
-rw-r--r-- | libstdc++-v3/include/experimental/any | 5 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc | 13 |
3 files changed, 25 insertions, 1 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index bbe34062d57..60cd825e063 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,6 +1,14 @@ 2017-02-14 Jonathan Wakely <jwakely@redhat.com> Backport from mainline + 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. + * testsuite/experimental/any/misc/any_cast.cc: Test non-copyable type. + + Backport from mainline 2017-01-18 Jonathan Wakely <jwakely@redhat.com> PR libstdc++/69301 diff --git a/libstdc++-v3/include/experimental/any b/libstdc++-v3/include/experimental/any index 5e091a45dda..1695f103b5c 100644 --- a/libstdc++-v3/include/experimental/any +++ b/libstdc++-v3/include/experimental/any @@ -425,7 +425,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/testsuite/experimental/any/misc/any_cast.cc b/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc index bb0f754f549..5d8e7fbfc95 100644 --- a/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc +++ b/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc @@ -106,9 +106,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(); } |