summaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2017-02-14 20:08:04 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2017-02-14 20:08:04 +0000
commit58868f8e89636148754e0e315874f5993b3dcd5b (patch)
tree247436e9f50cf36b2f761d3d9f5ababfe6a23adf /libstdc++-v3
parent059f7e17cb8e2e314ac635016b58015f18d283e2 (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--libstdc++-v3/include/experimental/any5
-rw-r--r--libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc13
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();
}