]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR69321 fix any_cast<T>(any*) for non-copyable T
authorJonathan Wakely <jwakely@redhat.com>
Tue, 14 Feb 2017 21:17:34 +0000 (21:17 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Tue, 14 Feb 2017 21:17:34 +0000 (21:17 +0000)
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.
* testsuite/experimental/any/misc/any_cast_neg.cc: Adjust dg-error.

From-SVN: r245458

libstdc++-v3/ChangeLog
libstdc++-v3/include/experimental/any
libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc
libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc

index af2007343cdd4fa0a42ed896069089cb1f67c319..7325a2f7e5442d03ea488c3a5d52e6ddb9f61592 100644 (file)
@@ -1,5 +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.
+       * testsuite/experimental/any/misc/any_cast_neg.cc: Adjust dg-error.
+
        Backport from mainline
        2017-01-18  Jonathan Wakely  <jwakely@redhat.com>
 
index 30cdf54c1925487cf5f4199ff113e32e0479a731..78fe39f2536ef26c3a3df6825ef2632e4bee8ef7 100644 (file)
@@ -236,14 +236,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     _Storage _M_storage;
 
     template<typename _Tp>
-      friend void* __any_caster(const any* __any)
-      {
-       if (__any->_M_manager != &_Manager<decay_t<_Tp>>::_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<typename _Tp>
@@ -347,6 +340,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
   // @}
 
+  template<typename _Tp>
+    void* __any_caster(const any* __any)
+    {
+      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);
+      return __arg._M_obj;
+    }
+
   /**
    * @brief Access the contained object.
    *
index f5d1d7723b19466c643af77ce17cc5aef48e08ab..ce4424ee0c39d098e2f7851dffcfad001bee59c6 100644 (file)
@@ -77,8 +77,21 @@ void test02()
   }
 }
 
+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();
+  test04();
 }
index 28388f68b0f3ef6ecb8fdeeec58ea2d151d654d6..7bc818a36b515649a1a28d00b58b3e3cd5153534 100644 (file)
@@ -26,5 +26,5 @@ void test01()
   using std::experimental::any_cast;
 
   const any y(1);
-  any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 311 }
+  any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 304 }
 }