diff mbox

PR77987 Fix unique_ptr<T[], D>::reset(U) for T != U

Message ID 20161019101053.GX2922@redhat.com
State New
Headers show

Commit Message

Jonathan Wakely Oct. 19, 2016, 10:10 a.m. UTC
On 17/10/16 13:00 +0100, Jonathan Wakely wrote:
>This is a very simple change, to allow conversions that are supposed

>to be valid according to DR 2118. The fix was slightly complicated by

>the tests being a bit of a mess. We had tests for this requirement,

>but they were in files which mixed positive tests and negative tests.

>I've split the tests so the invalid operations are in separate files

>and all the valid operations are in files that should pass.

>

>	PR libstdc++/77987

>	* include/bits/unique_ptr.h (unique_ptr<T[], D>::reset<U>(U)): Copy

>	value to pointer of the correct type to swap, to support conversions

>	allowed by LWG 2118 / N4089.

>	* testsuite/20_util/unique_ptr/assign/assign_neg.cc: Move test for

>	incompatible deleters from ...

>	* testsuite/20_util/unique_ptr/assign/cv_qual.cc: ... here.

>	* testsuite/20_util/unique_ptr/modifiers/cv_qual.cc: Move tests for

>	incompatible pointers to ...

>	* testsuite/20_util/unique_ptr/modifiers/reset_neg.cc: ... here. Move

>	destructor definition to base class. Test for invalid derived-to-base

>	conversion.

>

>I'll also backport this to the branches.


Here's another case where we have positive and negative tests in the
same file. I'm splitting this one too, and fixing one of the tests to
match its comment.

Tested powerpc64le-linux, comitted to trunk.
diff mbox

Patch

commit 721248b4e099769f0c78d72bf951e7b2d7b8f95a
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Oct 19 11:05:26 2016 +0100

    Move negative unique_ptr tests to new file
    
    	* testsuite/20_util/unique_ptr/cons/cv_qual.cc: Move negative tests
    	to new file.
    	* testsuite/20_util/unique_ptr/cons/cv_qual_neg.cc: New file.  Fix
    	test for incompatible deleters to not also use incompatible types.
    	Add tests for incompatible array types.

diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/cons/cv_qual.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/cons/cv_qual.cc
index 829d112..8d6847b 100644
--- a/libstdc++-v3/testsuite/20_util/unique_ptr/cons/cv_qual.cc
+++ b/libstdc++-v3/testsuite/20_util/unique_ptr/cons/cv_qual.cc
@@ -99,30 +99,4 @@  test07()
   std::unique_ptr<const A[]> cA2((A*)p);
   std::unique_ptr<volatile A[]> vA2((A*)p);
   std::unique_ptr<const volatile A[]> cvA2((A*)p);
-  // Disallow conversions from user-defined pointer-like types
-  // for the array version
-  std::unique_ptr<A[]> upA3(p); // { dg-error "no matching function" }
-  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 *-*-* } 446 }
 }
-
-template<typename T>
-struct deleter
-{
-  deleter() = default;
-  template<typename U>
-    deleter(const deleter<U>) { }
-  typedef T pointer;
-  void operator()(T) const { }
-};
-
-void
-test08()
-{
-  // Disallow conversions from non-assignable deleter
-  std::unique_ptr<B[], deleter<A_pointer>> p;
-  std::unique_ptr<A[], deleter<A*>> upA(std::move(p)); // { dg-error "no matching function" }
-}
-
diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/cons/cv_qual_neg.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/cons/cv_qual_neg.cc
new file mode 100644
index 0000000..d744c1b
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/unique_ptr/cons/cv_qual_neg.cc
@@ -0,0 +1,72 @@ 
+// { dg-do compile { target c++11 } }
+
+// Copyright (C) 2016 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/>.
+
+// 20.7.1 Class template unique_ptr [unique.ptr]
+
+#include <memory>
+
+struct A { virtual ~A() = default; };
+
+struct B : A { };
+
+// Construction from objects with different cv-qualification
+
+struct A_pointer { operator A*() const { return nullptr; } };
+
+void
+test07()
+{
+  A_pointer p;
+  // Disallow conversions from user-defined pointer-like types
+  // for the array version
+  std::unique_ptr<A[]> upA3(p); // { dg-error "no matching function" }
+  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 *-*-* } 446 }
+}
+
+template<typename T>
+struct deleter
+{
+  deleter() = default;
+  template<typename U>
+    deleter(const deleter<U>) { }
+  typedef T pointer;
+  void operator()(T) const { }
+};
+
+void
+test08()
+{
+  // Disallow conversions from non-assignable deleter
+  std::unique_ptr<A[], deleter<A_pointer>> p;
+  std::unique_ptr<A[], deleter<A*>> upA(std::move(p)); // { dg-error "no matching function" }
+}
+
+void
+test011()
+{
+  // Disallow conversions between different array types.
+  std::unique_ptr<B[]> upB;
+
+  std::unique_ptr<const A[]> cA(std::move(upB));  // { dg-error "no matching function" }
+  std::unique_ptr<volatile A[]> vA(std::move(upB)); // { dg-error "no matching function" }
+  std::unique_ptr<const volatile A[]> cvA(std::move(upB)); // { dg-error "no matching function" }
+}