[C++0x] fix libstdc++/43183 (unique_ptr::reset)

Jonathan Wakely jwakely.gcc@gmail.com
Tue Mar 2 00:41:00 GMT 2010


        PR libstdc++/43183
        * include/bits/unique_ptr.h (reset): Fix as per working paper.
        (operator*, operator->, operator[], operator bool, release): Use
        pointer's null value instead of 0.
        * testsuite/20_util/unique_ptr/assign/assign_neg.cc: Adjust.
        * testsuite/20_util/unique_ptr/modifiers/reset_neg.cc: Adjust.
        * testsuite/20_util/unique_ptr/modifiers/43183.cc: New.

Tested Linux/x86_64 and committed.
-------------- next part --------------
Index: include/bits/unique_ptr.h
===================================================================
--- include/bits/unique_ptr.h	(revision 157153)
+++ include/bits/unique_ptr.h	(working copy)
@@ -152,14 +152,14 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
       typename std::add_lvalue_reference<element_type>::type
       operator*() const
       {
-	_GLIBCXX_DEBUG_ASSERT(get() != 0);
+	_GLIBCXX_DEBUG_ASSERT(get() != pointer());
 	return *get();
       }
 
       pointer
       operator->() const
       {
-	_GLIBCXX_DEBUG_ASSERT(get() != 0);
+	_GLIBCXX_DEBUG_ASSERT(get() != pointer());
 	return get();
       }
 
@@ -178,25 +178,24 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
       { return std::get<1>(_M_t); }
 
       explicit operator bool() const
-      { return get() == 0 ? false : true; }
+      { return get() == pointer() ? false : true; }
 
       // Modifiers.
       pointer
       release() 
       {
 	pointer __p = get();
-	std::get<0>(_M_t) = 0;
+	std::get<0>(_M_t) = pointer();
 	return __p;
       }
 
       void
       reset(pointer __p = pointer())
       {
-	if (__p != get())
-	  {
-	    get_deleter()(get());
-	    std::get<0>(_M_t) = __p;
-	  }
+	using std::swap;
+	swap(std::get<0>(_M_t), __p);
+	if (__p != pointer())
+	  get_deleter()(__p);
       }
 
       void
@@ -293,7 +292,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
       typename std::add_lvalue_reference<element_type>::type 
       operator[](size_t __i) const 
       {
-	_GLIBCXX_DEBUG_ASSERT(get() != 0);
+	_GLIBCXX_DEBUG_ASSERT(get() != pointer());
 	return get()[__i];
       }
 
@@ -312,25 +311,24 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
       { return std::get<1>(_M_t); }    
 
       explicit operator bool() const 
-      { return get() == 0 ? false : true; }
+      { return get() == pointer() ? false : true; }
     
       // Modifiers.
       pointer
       release() 
       {
 	pointer __p = get();
-	std::get<0>(_M_t) = 0;
+	std::get<0>(_M_t) = pointer();
 	return __p;
       }
 
       void
       reset(pointer __p = pointer()) 
       {
-	if (__p != get())
-	{
-	  get_deleter()(get());
-	  std::get<0>(_M_t) = __p;
-	}
+	using std::swap;
+	swap(std::get<0>(_M_t), __p);
+	if (__p != pointer())
+	  get_deleter()(__p);
       }
 
       // DR 821.
Index: testsuite/20_util/unique_ptr/assign/assign_neg.cc
===================================================================
--- testsuite/20_util/unique_ptr/assign/assign_neg.cc	(revision 157153)
+++ testsuite/20_util/unique_ptr/assign/assign_neg.cc	(working copy)
@@ -49,7 +49,7 @@ test03()
   std::unique_ptr<int[2]> p2 = p1;
 }
 
-// { dg-error "deleted function" "" { target *-*-* } 348 }
+// { dg-error "deleted function" "" { target *-*-* } 346 }
 // { dg-error "used here" "" { target *-*-* } 42 }
 // { dg-error "no matching" "" { target *-*-* } 48 }
 // { dg-warning "candidates are" "" { target *-*-* } 115 }
@@ -57,5 +57,5 @@ test03()
 // { dg-warning "note" "" { target *-*-* } 103 }
 // { dg-warning "note" "" { target *-*-* } 98 }
 // { dg-warning "note" "" { target *-*-* } 92 }
-// { dg-error "deleted function" "" { target *-*-* } 210 }
+// { dg-error "deleted function" "" { target *-*-* } 209 }
 // { dg-error "used here" "" { target *-*-* } 49 }
Index: testsuite/20_util/unique_ptr/modifiers/reset_neg.cc
===================================================================
--- testsuite/20_util/unique_ptr/modifiers/reset_neg.cc	(revision 157153)
+++ testsuite/20_util/unique_ptr/modifiers/reset_neg.cc	(working copy)
@@ -36,4 +36,4 @@ void test01()
 }
 
 // { dg-error "used here" "" { target *-*-* } 35 } 
-// { dg-error "deleted function" "" { target *-*-* } 338 }
+// { dg-error "deleted function" "" { target *-*-* } 336 }
Index: testsuite/20_util/unique_ptr/modifiers/43183.cc
===================================================================
--- testsuite/20_util/unique_ptr/modifiers/43183.cc	(revision 0)
+++ testsuite/20_util/unique_ptr/modifiers/43183.cc	(revision 0)
@@ -0,0 +1,55 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2010 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
+// 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.9.10.2.5 unique_ptr modifiers [unique.ptr.single.modifiers]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct D
+{
+  static int count;
+
+  void operator()(int* p) const
+  {
+    ++count;
+    delete p;
+  }
+};
+int D::count = 0;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  std::unique_ptr<int, D> up;
+  up.reset();
+  VERIFY( D::count == 0 );
+  up.reset(new int);
+  VERIFY( D::count == 0 );
+  up.reset(up.get());
+  VERIFY( D::count == 1 );
+  up.release();
+}
+
+int main()
+{
+  test01();
+  return 0;
+}


More information about the Libstdc++ mailing list