Patchwork [google,4_7] backport "std::unique_ptr<T[], D> improvements"

login
register
mail settings
Submitter Lawrence Crowl
Date Jan. 3, 2013, 11:46 p.m.
Message ID <CAGqM8fZHKm2bp63qrCS0eXOF3gJaVdNzO_1k0YMVzf8w_CErrg@mail.gmail.com>
Download mbox | patch
Permalink /patch/209338/
State New
Headers show

Comments

Lawrence Crowl - Jan. 3, 2013, 11:46 p.m.
Relax the restrictions on argument types to a unique_ptr
instantiated on an array type.  This patch is a backport
of Jonathan Wakely's "std::unique_ptr<T[], D> improvements"
http://gcc.gnu.org/ml/gcc-patches/2012-12/msg01271.html to the
google 4.7 branch.

The existing unique_ptr admits no conversions, not even
cv-qualification conversions.  The patch permits cv-qualification
conversion.  It prohibits derived-to-base pointer conversion, as
is needed to prevent improper deletion.  It permits user-defined
pointer types.  The latter permissiveness is under debate.  Given

  struct base { };
  struct derived : base { };

as we cannot presently distinguish between the safe

  struct ptr_base {
    operator base*() { return 0; }
  };

  ... unique_ptr< base >( ptr_base() );

and the unsafe

  struct ptr_derived {
    operator derived*() { return 0; }
  };

  ... unique_ptr< base >( ptr_derived() );

No existing code can encounter the unsafe part because no existing
code can have user-defined pointer types.  There are likely to be
very few uses of user-defined pointers introduced into the code
base between now and when the issue is resolved.  So, backporting
the patch as is seems safe enough, and not too much trouble to
correct later.

Tested on x86_64.  Tests pass through Google's core and mantle,
but fail for apparently unrelated reasons in crust.

Okay for branch?


Index: libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc
===================================================================
--- libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc	(revision
194742)
+++ libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc	(working copy)
@@ -19,7 +19,7 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.

-// { dg-error "static assertion failed" "" { target *-*-* } 1776 }
+// { dg-error "static assertion failed" "" { target *-*-* } 1778 }

 #include <utility>
Paul Pluzhnikov - Jan. 3, 2013, 11:52 p.m.
On Thu, Jan 3, 2013 at 3:46 PM, Lawrence Crowl <crowl@googlers.com> wrote:
> Relax the restrictions on argument types to a unique_ptr
> instantiated on an array type.  This patch is a backport
> of Jonathan Wakely's "std::unique_ptr<T[], D> improvements"
> http://gcc.gnu.org/ml/gcc-patches/2012-12/msg01271.html to the
> google 4.7 branch.

Approved for google/gcc-4_7 branch.

Thanks,

Patch

Index: libstdc++-v3/include/std/type_traits
===================================================================
--- libstdc++-v3/include/std/type_traits	(revision 194742)
+++ libstdc++-v3/include/std/type_traits	(working copy)
@@ -1723,6 +1723,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct enable_if<true, _Tp>
     { typedef _Tp type; };

+  template<typename... _Cond>
+    using _Require = typename enable_if<__and_<_Cond...>::value>::type;

   // Primary template.
   /// Define a member typedef @c type to one of two argument types.
Index: libstdc++-v3/include/bits/unique_ptr.h
===================================================================
--- libstdc++-v3/include/bits/unique_ptr.h	(revision 194742)
+++ libstdc++-v3/include/bits/unique_ptr.h	(working copy)
@@ -52,7 +52,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       constexpr default_delete() noexcept = default;

       template<typename _Up, typename = typename
-	       std::enable_if<std::is_convertible<_Up*, _Tp*>::value>::type>
+	       enable_if<is_convertible<_Up*, _Tp*>::value>::type>
         default_delete(const default_delete<_Up>&) noexcept { }

       void
@@ -70,8 +70,23 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp>
     struct default_delete<_Tp[]>
     {
+    private:
+      template<typename _Up>
+	using __remove_cv = typename remove_cv<_Up>::type;
+
+      // Like is_base_of<_Tp, _Up> but false if unqualified types are the same
+      template<typename _Up>
+	using __is_derived_Tp
+	  = __and_< is_base_of<_Tp, _Up>,
+		    __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
+
+    public:
       constexpr default_delete() noexcept = default;

+      template<typename _Up, typename = typename
+	       enable_if<!__is_derived_Tp<_Up>::value>::type>
+        default_delete(const default_delete<_Up[]>&) noexcept { }
+
       void
       operator()(_Tp* __ptr) const
       {
@@ -80,7 +95,9 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	delete [] __ptr;
       }

-      template<typename _Up> void operator()(_Up*) const = delete;
+      template<typename _Up>
+	typename enable_if<__is_derived_Tp<_Up>::value>::type
+	operator()(_Up*) const = delete;
     };

   /// 20.7.12.2 unique_ptr for single objects.
@@ -99,7 +116,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	typedef typename remove_reference<_Dp>::type _Del;

       public:
-	typedef decltype( __test<_Del>(0)) type;
+	typedef decltype(__test<_Del>(0)) type;
       };

       typedef std::tuple<typename _Pointer::type, _Dp>  __tuple_type;
@@ -113,54 +130,45 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       // Constructors.
       constexpr unique_ptr() noexcept
       : _M_t()
-      { static_assert(!std::is_pointer<deleter_type>::value,
+      { static_assert(!is_pointer<deleter_type>::value,
 		     "constructed with null function pointer deleter"); }

       explicit
       unique_ptr(pointer __p) noexcept
       : _M_t(__p, deleter_type())
-      { static_assert(!std::is_pointer<deleter_type>::value,
+      { static_assert(!is_pointer<deleter_type>::value,
 		     "constructed with null function pointer deleter"); }

       unique_ptr(pointer __p,
-	  typename std::conditional<std::is_reference<deleter_type>::value,
+	  typename std::conditional<is_reference<deleter_type>::value,
 	    deleter_type, const deleter_type&>::type __d) noexcept
       : _M_t(__p, __d) { }

       unique_ptr(pointer __p,
-	  typename std::remove_reference<deleter_type>::type&& __d) noexcept
+	  typename remove_reference<deleter_type>::type&& __d) noexcept
       : _M_t(std::move(__p), std::move(__d))
       { static_assert(!std::is_reference<deleter_type>::value,
 		      "rvalue deleter bound to reference"); }

-      constexpr unique_ptr(nullptr_t) noexcept
-      : _M_t()
-      { static_assert(!std::is_pointer<deleter_type>::value,
-		     "constructed with null function pointer deleter"); }
+      constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }

       // Move constructors.
       unique_ptr(unique_ptr&& __u) noexcept
       : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }

-      template<typename _Up, typename _Ep, typename = typename
-	std::enable_if
-	  <std::is_convertible<typename unique_ptr<_Up, _Ep>::pointer,
-			       pointer>::value
-	   && !std::is_array<_Up>::value
-	   && ((std::is_reference<_Dp>::value
-		&& std::is_same<_Ep, _Dp>::value)
-	       || (!std::is_reference<_Dp>::value
-		   && std::is_convertible<_Ep, _Dp>::value))>
-	     ::type>
+      template<typename _Up, typename _Ep, typename = _Require<
+	      is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
+	      __not_<is_array<_Up>>,
+	      typename conditional<is_reference<_Dp>::value,
+				   is_same<_Ep, _Dp>,
+				   is_convertible<_Ep, _Dp>>::type>>
 	unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
 	: _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
 	{ }

 #if _GLIBCXX_USE_DEPRECATED
-      template<typename _Up, typename = typename
-	std::enable_if<std::is_convertible<_Up*, _Tp*>::value
-		       && std::is_same<_Dp,
-				       default_delete<_Tp>>::value>::type>
+	template<typename _Up, typename = _Require<
+		is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>>
 	unique_ptr(auto_ptr<_Up>&& __u) noexcept
 	: _M_t(__u.release(), deleter_type()) { }
 #endif
@@ -183,12 +191,12 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	return *this;
       }

-      template<typename _Up, typename _Ep, typename = typename
-	std::enable_if
-	  <std::is_convertible<typename unique_ptr<_Up, _Ep>::pointer,
-			       pointer>::value
-	   && !std::is_array<_Up>::value>::type>
-	unique_ptr&
+      template<typename _Up, typename _Ep>
+	typename enable_if< __and_<
+	  is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
+	  __not_<is_array<_Up>>
+	  >::value,
+	  unique_ptr&>::type
 	operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
 	{
 	  reset(__u.release());
@@ -204,7 +212,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }

       // Observers.
-      typename std::add_lvalue_reference<element_type>::type
+      typename add_lvalue_reference<element_type>::type
       operator*() const
       {
 	_GLIBCXX_DEBUG_ASSERT(get() != pointer());
@@ -270,11 +278,47 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp, typename _Dp>
     class unique_ptr<_Tp[], _Dp>
     {
-      typedef std::tuple<_Tp*, _Dp>  	__tuple_type;
-      __tuple_type 			_M_t;
+      // use SFINAE to determine whether _Del::pointer exists
+      class _Pointer
+      {
+	template<typename _Up>
+	  static typename _Up::pointer __test(typename _Up::pointer*);
+
+	template<typename _Up>
+	  static _Tp* __test(...);
+
+	typedef typename remove_reference<_Dp>::type _Del;
+
+      public:
+	typedef decltype(__test<_Del>(0)) type;
+      };
+
+      typedef std::tuple<typename _Pointer::type, _Dp>  __tuple_type;
+      __tuple_type                                      _M_t;
+
+      template<typename _Up>
+	using __remove_cv = typename remove_cv<_Up>::type;
+
+      // like is_base_of<_Tp, _Up> but false if unqualified types are the same
+      template<typename _Up>
+	using __is_derived_Tp
+	  = __and_< is_base_of<_Tp, _Up>,
+		    __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
+
+      template<typename _Up, typename _Ep,
+	       typename _Tp_pointer = typename _Pointer::type,
+	       typename _Up_pointer = typename unique_ptr<_Up, _Ep>::pointer>
+	using __safe_conversion = __and_<
+	    is_convertible<_Up_pointer, _Tp_pointer>,
+	    is_array<_Up>,
+	    __or_<__not_<is_pointer<_Up_pointer>>,
+		  __not_<is_pointer<_Tp_pointer>>,
+		  __not_<__is_derived_Tp<typename remove_extent<_Up>::type>>
+	    >
+	  >;

     public:
-      typedef _Tp*		 	pointer;
+      typedef typename _Pointer::type	pointer;
       typedef _Tp		 	element_type;
       typedef _Dp                       deleter_type;

@@ -282,35 +326,42 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       constexpr unique_ptr() noexcept
       : _M_t()
       { static_assert(!std::is_pointer<deleter_type>::value,
-		     "constructed with null function pointer deleter"); }
+		      "constructed with null function pointer deleter"); }

       explicit
       unique_ptr(pointer __p) noexcept
       : _M_t(__p, deleter_type())
-      { static_assert(!std::is_pointer<deleter_type>::value,
-		     "constructed with null function pointer deleter"); }
+      { static_assert(!is_pointer<deleter_type>::value,
+		      "constructed with null function pointer deleter"); }
+
+      template<typename _Up, typename = _Require<is_pointer<pointer>,
+	       is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>>
+	explicit
+	unique_ptr(_Up* __p) = delete;

       unique_ptr(pointer __p,
-	  typename std::conditional<std::is_reference<deleter_type>::value,
+	  typename conditional<is_reference<deleter_type>::value,
 	      deleter_type, const deleter_type&>::type __d) noexcept
       : _M_t(__p, __d) { }

       unique_ptr(pointer __p, typename
-		 std::remove_reference<deleter_type>::type && __d) noexcept
+		 remove_reference<deleter_type>::type&& __d) noexcept
       : _M_t(std::move(__p), std::move(__d))
-      { static_assert(!std::is_reference<deleter_type>::value,
+      { static_assert(!is_reference<deleter_type>::value,
 		      "rvalue deleter bound to reference"); }

-      constexpr unique_ptr(nullptr_t) noexcept
-      : _M_t()
-      { static_assert(!std::is_pointer<deleter_type>::value,
-		     "constructed with null function pointer deleter"); }
-
-      // Move constructors.
+      // Move constructor.
       unique_ptr(unique_ptr&& __u) noexcept
       : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }

-      template<typename _Up, typename _Ep>
+      constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
+
+      template<typename _Up, typename _Ep,
+	       typename = _Require<__safe_conversion<_Up, _Ep>,
+		 typename conditional<is_reference<_Dp>::value,
+				      is_same<_Ep, _Dp>,
+				      is_convertible<_Ep, _Dp>>::type
+	       >>
 	unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
 	: _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
 	{ }
@@ -334,7 +385,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }

       template<typename _Up, typename _Ep>
-	unique_ptr&
+	typename
+	enable_if<__safe_conversion<_Up, _Ep>::value, unique_ptr&>::type
 	operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
 	{
 	  reset(__u.release());
@@ -382,26 +434,21 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }

       void
-      reset(pointer __p = pointer()) noexcept
-      {
-	using std::swap;
-	swap(std::get<0>(_M_t), __p);
-	if (__p != nullptr)
-	  get_deleter()(__p);
-      }
+      reset() noexcept
+      { reset(pointer()); }

       void
-      reset(nullptr_t) noexcept
+      reset(pointer __p) noexcept
       {
-	pointer __p = get();
-	std::get<0>(_M_t) = pointer();
+	using std::swap;
+	swap(std::get<0>(_M_t), __p);
 	if (__p != nullptr)
 	  get_deleter()(__p);
       }

-      // DR 821.
-      template<typename _Up>
-	void reset(_Up) = delete;
+      template<typename _Up, typename = _Require<is_pointer<pointer>,
+	       is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>>
+	void reset(_Up*) = delete;

       void
       swap(unique_ptr& __u) noexcept
@@ -415,23 +462,16 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       unique_ptr& operator=(const unique_ptr&) = delete;

       // Disable construction from convertible pointer types.
-      // (N2315 - 20.6.5.3.1)
-      template<typename _Up>
+      template<typename _Up, typename = _Require<is_pointer<pointer>,
+	       is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>>
 	unique_ptr(_Up*, typename
-		   std::conditional<std::is_reference<deleter_type>::value,
-		   deleter_type, const deleter_type&>::type,
-		   typename std::enable_if<std::is_convertible<_Up*,
-		   pointer>::value>::type* = 0) = delete;
-
-      template<typename _Up>
-	unique_ptr(_Up*, typename std::remove_reference<deleter_type>::type&&,
-		   typename std::enable_if<std::is_convertible<_Up*,
-		   pointer>::value>::type* = 0) = delete;
+		   conditional<is_reference<deleter_type>::value,
+		   deleter_type, const deleter_type&>::type) = delete;

-      template<typename _Up>
-	explicit
-	unique_ptr(_Up*, typename std::enable_if<std::is_convertible<_Up*,
-		   pointer>::value>::type* = 0) = delete;
+      template<typename _Up, typename = _Require<is_pointer<pointer>,
+	       is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>>
+	unique_ptr(_Up*, typename
+		   remove_reference<deleter_type>::type&&) = delete;
     };

   template<typename _Tp, typename _Dp>
Index: libstdc++-v3/include/bits/shared_ptr_base.h
===================================================================
--- libstdc++-v3/include/bits/shared_ptr_base.h	(revision 194742)
+++ libstdc++-v3/include/bits/shared_ptr_base.h	(working copy)
@@ -621,7 +621,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	_S_create_from_up(std::unique_ptr<_Tp, _Del>&& __r,
 	  typename std::enable_if<!std::is_reference<_Del>::value>::type* = 0)
 	{
-	  return new _Sp_counted_deleter<_Tp*, _Del, std::allocator<void>,
+	  typedef typename unique_ptr<_Tp, _Del>::pointer _Ptr;
+	  return new _Sp_counted_deleter<_Ptr, _Del, std::allocator<void>,
 	    _Lp>(__r.get(), __r.get_deleter());
 	}

@@ -630,9 +631,10 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	_S_create_from_up(std::unique_ptr<_Tp, _Del>&& __r,
 	  typename std::enable_if<std::is_reference<_Del>::value>::type* = 0)
 	{
+	  typedef typename unique_ptr<_Tp, _Del>::pointer _Ptr;
 	  typedef typename std::remove_reference<_Del>::type _Del1;
 	  typedef std::reference_wrapper<_Del1> _Del2;
-	  return new _Sp_counted_deleter<_Tp*, _Del2, std::allocator<void>,
+	  return new _Sp_counted_deleter<_Ptr, _Del2, std::allocator<void>,
 	    _Lp>(__r.get(), std::ref(__r.get_deleter()));
 	}

@@ -851,7 +853,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	: _M_ptr(__r.get()), _M_refcount()
 	{
 	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
-	  _Tp1* __tmp = __r.get();
+	  auto __tmp = std::__addressof(*__r.get());
 	  _M_refcount = __shared_count<_Lp>(std::move(__r));
 	  __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
 	}
Index: libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc
===================================================================
--- libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc	(revision
194742)
+++ libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc	(working copy)
@@ -32,9 +32,9 @@  void test01()
 {
   X* px = 0;
   std::shared_ptr<X> p1(px);   // { dg-error "here" }
-  // { dg-error "incomplete" "" { target *-*-* } 775 }
+  // { dg-error "incomplete" "" { target *-*-* } 777 }

   std::shared_ptr<X> p9(ap());  // { dg-error "here" }
-  // { dg-error "incomplete" "" { target *-*-* } 869 }
+  // { dg-error "incomplete" "" { target *-*-* } 871 }

 }
Index: libstdc++-v3/testsuite/20_util/shared_ptr/cons/unique_ptr.cc
===================================================================
--- libstdc++-v3/testsuite/20_util/shared_ptr/cons/unique_ptr.cc	(revision
194742)
+++ libstdc++-v3/testsuite/20_util/shared_ptr/cons/unique_ptr.cc	(working copy)
@@ -1,6 +1,6 @@ 
-// { dg-options "-std=gnu++0x" }
+// { dg-options "-std=gnu++11" }

-// Copyright (C) 2008, 2009 Free Software Foundation
+// Copyright (C) 2008-2012 Free Software Foundation
 //
 // 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
@@ -17,14 +17,14 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.

-// 20.7.12.2 Template class shared_ptr [util.smartptr.shared]
+// 20.7.2.2 Class template shared_ptr [util.smartptr.shared]

 #include <memory>
 #include <testsuite_hooks.h>

 struct A { };

-// 20.7.12.2.1 shared_ptr constructors [util.smartptr.shared.const]
+// 20.7.2.2.1 shared_ptr constructors [util.smartptr.shared.const]

 // Construction from unique_ptr
 int
Index: libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc
===================================================================
--- libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc	(revision
194742)
+++ libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc	(working
copy)
@@ -1,7 +1,7 @@ 
 // { dg-do compile }
 // { dg-options "-std=gnu++0x" }

-// Copyright (C) 2008, 2009, 2010 Free Software Foundation
+// Copyright (C) 2008-2012 Free Software Foundation
 //
 // 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
@@ -32,7 +32,7 @@  struct B : A
 void test01()
 {
   std::unique_ptr<B[]> up;
-  up.reset(new A[3]);		// { dg-error "deleted" }
+  up.reset(new A[3]);		// { dg-error "invalid conversion" }
 }

 // { dg-prune-output "include" }
Index: libstdc++-v3/testsuite/20_util/unique_ptr/cons/ptr_deleter_neg.cc
===================================================================
--- libstdc++-v3/testsuite/20_util/unique_ptr/cons/ptr_deleter_neg.cc	(revision
194742)
+++ libstdc++-v3/testsuite/20_util/unique_ptr/cons/ptr_deleter_neg.cc	(working
copy)
@@ -1,7 +1,7 @@ 
 // { dg-options "-std=gnu++0x" }
 // { dg-do compile }

-// Copyright (C) 2010 Free Software Foundation
+// Copyright (C) 2010-2012 Free Software Foundation
 //
 // 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
@@ -18,10 +18,9 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.

-// 20.6.11 Template class unique_ptr [unique.ptr]
+// 20.7.1 Class template unique_ptr [unique.ptr]

 #include <memory>
-#include <testsuite_hooks.h>

 using std::unique_ptr;

@@ -30,9 +29,9 @@  using std::unique_ptr;
 void
 test01()
 {
-  unique_ptr<int, void(*)(int*)> p1; // { dg-error "here" }
+  unique_ptr<long, void(*)(long*)> p1; // { dg-error "here" }

-  unique_ptr<int, void(*)(int*)> p2(nullptr); // { dg-error "here" }
+  unique_ptr<short, void(*)(short*)> p2(nullptr); // { dg-error "here" }

   unique_ptr<int, void(*)(int*)> p3(new int); // { dg-error "here" }
 }
@@ -40,9 +39,9 @@  test01()
 void
 test02()
 {
-  unique_ptr<int[], void(*)(int*)> p1; // { dg-error "here" }
+  unique_ptr<long[], void(*)(long*)> p1; // { dg-error "here" }

-  unique_ptr<int[], void(*)(int*)> p2(nullptr); // { dg-error "here" }
+  unique_ptr<short[], void(*)(short*)> p2(nullptr); // { dg-error "here" }

   unique_ptr<int[], void(*)(int*)> p3(new int[1]); // { dg-error "here" }
 }
Index: libstdc++-v3/testsuite/20_util/unique_ptr/cons/pointer_array_convertible_neg.cc
===================================================================
--- libstdc++-v3/testsuite/20_util/unique_ptr/cons/pointer_array_convertible_neg.cc	(revision
194742)
+++ libstdc++-v3/testsuite/20_util/unique_ptr/cons/pointer_array_convertible_neg.cc	(working
copy)
@@ -1,7 +1,7 @@ 
 // { dg-do compile }
-// { dg-options "-std=gnu++0x" }
+// { dg-options "-std=gnu++11" }

-// Copyright (C) 2008, 2009 Free Software Foundation
+// Copyright (C) 2008-2012 Free Software Foundation
 //
 // 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
@@ -29,7 +29,7 @@  struct B : A
   virtual ~B() { }
 };

-// 20.4.5.1 unique_ptr constructors [unique.ptr.cons]
+// 20.7.1.3.1 unique_ptr constructors [unique.ptr.runtime.ctor]

 // Construction from pointer of derived type
 void
Index: libstdc++-v3/testsuite/20_util/unique_ptr/requirements/pointer_type.cc
===================================================================
--- libstdc++-v3/testsuite/20_util/unique_ptr/requirements/pointer_type.cc	(revision
194742)
+++ libstdc++-v3/testsuite/20_util/unique_ptr/requirements/pointer_type.cc	(working
copy)
@@ -1,7 +1,7 @@ 
 // { dg-do compile }
-// { dg-options "-std=gnu++0x" }
+// { dg-options "-std=gnu++11" }

-// Copyright (C) 2010, 2011 Free Software Foundation
+// Copyright (C) 2010-2012 Free Software Foundation
 //
 // 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
@@ -18,10 +18,9 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.

-// 20.6.11 Template class unique_ptr [unique.ptr.single]
+// 20.7.1.2 unique_ptr for single objects [unique.ptr.single]

 #include <memory>
-#include <testsuite_hooks.h>

 struct A
 {
Index: libstdc++-v3/testsuite/20_util/unique_ptr/assign/48635_neg.cc
===================================================================
--- libstdc++-v3/testsuite/20_util/unique_ptr/assign/48635_neg.cc	(revision
194742)
+++ libstdc++-v3/testsuite/20_util/unique_ptr/assign/48635_neg.cc	(working copy)
@@ -41,10 +41,10 @@  void f()
   std::unique_ptr<int, B&> ub(nullptr, b);
   std::unique_ptr<int, D&> ud(nullptr, d);
   ub = std::move(ud);
-// { dg-error "use of deleted function" "" { target *-*-* } 195 }
+// { dg-error "use of deleted function" "" { target *-*-* } 203 }

   std::unique_ptr<int[], B&> uba(nullptr, b);
   std::unique_ptr<int[], D&> uda(nullptr, d);
   uba = std::move(uda);
-// { dg-error "use of deleted function" "" { target *-*-* } 341 }
+// { dg-error "use of deleted function" "" { target *-*-* } 393 }
 }
Index: libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc
===================================================================
--- libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc	(revision 194742)
+++ libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc	(working copy)
@@ -27,4 +27,4 @@  struct D : B { };
 D d;
 std::default_delete<B[]> db;
 typedef decltype(db(&d)) type; // { dg-error "use of deleted function" }
-// { dg-error "declared here" "" { target *-*-* } 83 }
+// { dg-error "declared here" "" { target *-*-* } 100 }