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.

commit 721248b4e099769f0c78d72bf951e7b2d7b8f95a
Author: Jonathan Wakely <jwak...@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" }
+}

Reply via email to