]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR libstdc++/87704 fix unique_ptr(nullptr_t) constructors
authorJonathan Wakely <jwakely@redhat.com>
Thu, 25 Oct 2018 16:41:54 +0000 (17:41 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Thu, 25 Oct 2018 16:41:54 +0000 (17:41 +0100)
Using a delegating constructor to implement these constructors means
that they instantiate the destructor, which requires the element_type to
be complete. In C++11 and C++14 they were specified to be delegating,
but that was changed as part of LWG 2801 so in C++17 they don't require
a complete type (as was intended all along).

Backport from mainline
2018-10-23  Jonathan Wakely  <jwakely@redhat.com>

PR libstdc++/87704
* include/bits/unique_ptr.h (unique_ptr::unique_ptr(nullptr_t)): Do
not delegate to default constructor.
(unique_ptr<T[], D>::unique_ptr(nullptr_t)): Likewise.
* testsuite/20_util/unique_ptr/cons/incomplete.cc: New test.

From-SVN: r265499

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/unique_ptr.h
libstdc++-v3/testsuite/20_util/unique_ptr/assign/48635_neg.cc
libstdc++-v3/testsuite/20_util/unique_ptr/cons/cv_qual_neg.cc
libstdc++-v3/testsuite/20_util/unique_ptr/cons/incomplete.cc [new file with mode: 0644]

index 4024fc9e449f05eb0b5f14dcc63023b971d83f74..eb2b9b3c2f8298be365d04d2692fd52dd4b3afa4 100644 (file)
@@ -1,3 +1,17 @@
+2018-10-25  Jonathan Wakely  <jwakely@redhat.com>
+
+
+       Backport from mainline
+       2018-10-23  Jonathan Wakely  <jwakely@redhat.com>
+
+       PR libstdc++/87704
+       * include/bits/unique_ptr.h (unique_ptr::unique_ptr(nullptr_t)): Do
+       not delegate to default constructor.
+       (unique_ptr<T[], D>::unique_ptr(nullptr_t)): Likewise.
+       * testsuite/20_util/unique_ptr/cons/incomplete.cc: New test.
+       * testsuite/20_util/unique_ptr/assign/48635_neg.cc: Adjust dg-error.
+       * testsuite/20_util/unique_ptr/cons/cv_qual_neg.cc: Likewise.
+
 2018-10-18  Jonathan Wakely  <jwakely@redhat.com>
 
        Backport from mainline
index 8e302877f78a2a99a35db41902131dba3a97dd97..93c579788b63748456fe4c75a1e1fec017177d43 100644 (file)
@@ -201,7 +201,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                      "rvalue deleter bound to reference"); }
 
       /// Creates a unique_ptr that owns nothing.
-      constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
+      constexpr unique_ptr(nullptr_t) noexcept : _M_t()
+      { static_assert(!is_pointer<deleter_type>::value,
+                     "constructed with null function pointer deleter"); }
 
       // Move constructors.
 
@@ -491,7 +493,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
 
       /// Creates a unique_ptr that owns nothing.
-      constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
+      constexpr unique_ptr(nullptr_t) noexcept : _M_t()
+      { static_assert(!is_pointer<deleter_type>::value,
+                     "constructed with null function pointer deleter"); }
 
       template<typename _Up, typename _Ep,
               typename = _Require<__safe_conversion_up<_Up, _Ep>>>
index 785f9ad4cfdbd6ff1ec1a6f42c319d4dabcc18e6..e64b4535345efb2eb89194ecaf1278f82c52155b 100644 (file)
@@ -43,10 +43,10 @@ void f()
   std::unique_ptr<int, D&> ud(nullptr, d);
   ub = std::move(ud); // { dg-error "no match" }
   ub2 = ud; // { dg-error "no match" }
-// { dg-error "no type" "" { target *-*-* } 272 }
+// { dg-error "no type" "" { target *-*-* } 274 }
 
   std::unique_ptr<int[], B&> uba(nullptr, b);
   std::unique_ptr<int[], D&> uda(nullptr, d);
   uba = std::move(uda); // { dg-error "no match" }
-// { dg-error "no type" "" { target *-*-* } 540 }
+// { dg-error "no type" "" { target *-*-* } 544 }
 }
index 285a0b994c9cb25b2ee599fb85807154b13d7812..9b8cba45a57decae2ea901a69edfae3cf01669dc 100644 (file)
@@ -40,7 +40,7 @@ test07()
   std::unique_ptr<const A[]> cA3(p); // { dg-error "no matching function" }
   std::unique_ptr<volatile A[]> vA3(p); // { dg-error "no matching function" }
   std::unique_ptr<const volatile A[]> cvA3(p); // { dg-error "no matching function" }
-  // { dg-error "no type" "" { target *-*-* } 448 }
+  // { dg-error "no type" "" { target *-*-* } 450 }
 }
 
 template<typename T>
diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/cons/incomplete.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/cons/incomplete.cc
new file mode 100644 (file)
index 0000000..1a8f288
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright (C) 2018 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++11 } }
+
+#include <memory>
+
+struct Incomplete;
+
+void f(void** p)
+{
+  ::new (p[0]) std::unique_ptr<Incomplete>();
+  ::new (p[1]) std::unique_ptr<Incomplete[]>();
+
+  // PR libstdc++/87704
+  ::new (p[2]) std::unique_ptr<Incomplete>(nullptr);
+  ::new (p[3]) std::unique_ptr<Incomplete[]>(nullptr);
+}