Patchwork [v3] Extend smart ptr assertions to reject void*

login
register
mail settings
Submitter Jonathan Wakely
Date Oct. 30, 2013, 7:49 p.m.
Message ID <CAH6eHdQUUzFiLm86vjPTHwTr1derPO+KEBO0nbvaYhn22C0gtg@mail.gmail.com>
Download mbox | patch
Permalink /patch/287332/
State New
Headers show

Comments

Jonathan Wakely - Oct. 30, 2013, 7:49 p.m.
Because of the GNU extension that allows sizeof(void) we fail to
reject ill-formed programs. This patch fixes that.

2013-10-30  Jonathan Wakely  <jwakely.gcc@gmail.com>

        * include/bits/shared_ptr (__shared_ptr): Assert non-void pointer.
        * include/bits/shared_ptr (default_delete): Likewise.
        * include/backward/auto_ptr.h (__shared_ptr(auto_ptr&&)): Likewise.
        * testsuite/20_util/shared_ptr/cons/58839.cc: Do not use
        default_delete<void>.
        * testsuite/20_util/shared_ptr/cons/void_neg.cc: New.
        * testsuite/20_util/default_delete/void_neg.cc: New.
        * testsuite/20_util/shared_ptr/cons/43820_neg.cc: Adjust line numbers.
        * testsuite/20_util/unique_ptr/assign/48635_neg.cc: Likewise.

Tested x86_64-linux, committed to trunk.
commit 5b0ffcc57b7126016eda484e56eda3eba0a0ec90
Author: Jonathan Wakely <jwakely.gcc@gmail.com>
Date:   Wed Oct 30 17:50:39 2013 +0000

    	* include/bits/shared_ptr (__shared_ptr): Assert non-void pointer.
    	* include/bits/shared_ptr (default_delete): Likewise.
    	* testsuite/20_util/shared_ptr/cons/58839.cc: Do not use
    	default_delete<void>.
    	* testsuite/20_util/shared_ptr/cons/void_neg.cc: New.
    	* testsuite/20_util/default_delete/void_neg.cc: New.
    	* testsuite/20_util/shared_ptr/cons/43820_neg.cc: Adjust line numbers.
    	* testsuite/20_util/unique_ptr/assign/48635_neg.cc: Likewise.

Patch

diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h
index 91b6367..cf90d7a 100644
--- a/libstdc++-v3/include/bits/shared_ptr_base.h
+++ b/libstdc++-v3/include/bits/shared_ptr_base.h
@@ -775,6 +775,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
         : _M_ptr(__p), _M_refcount(__p)
 	{
 	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
+	  static_assert( !is_void<_Tp>::value, "incomplete type" );
 	  static_assert( sizeof(_Tp1) > 0, "incomplete type" );
 	  __enable_shared_from_this_helper(_M_refcount, __p, __p);
 	}
diff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h
index c6c9a5a..bfe40ec 100644
--- a/libstdc++-v3/include/bits/unique_ptr.h
+++ b/libstdc++-v3/include/bits/unique_ptr.h
@@ -69,6 +69,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       void
       operator()(_Tp* __ptr) const
       {
+	static_assert(!is_void<_Tp>::value,
+		      "can't delete pointer to incomplete type");
 	static_assert(sizeof(_Tp)>0,
 		      "can't delete pointer to incomplete type");
 	delete __ptr;
diff --git a/libstdc++-v3/testsuite/20_util/default_delete/void_neg.cc b/libstdc++-v3/testsuite/20_util/default_delete/void_neg.cc
new file mode 100644
index 0000000..79786cb
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/default_delete/void_neg.cc
@@ -0,0 +1,30 @@ 
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+// Copyright (C) 2013 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.8.1.1 Default deleters [util.ptr.dltr]
+
+#include <memory>
+
+void test01()
+{
+  std::default_delete<void> d;
+  d(nullptr);   // { dg-error "here" }
+  // { dg-error "incomplete" "" { target *-*-* } 72 }
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc
index fd2a677..db3fcac 100644
--- a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc
@@ -32,7 +32,7 @@  void test01()
 {
   X* px = 0;
   std::shared_ptr<X> p1(px);   // { dg-error "here" }
-  // { dg-error "incomplete" "" { target *-*-* } 778 }
+  // { dg-error "incomplete" "" { target *-*-* } 779 }
 
   std::shared_ptr<X> p9(ap());  // { dg-error "here" }
   // { dg-error "incomplete" "" { target *-*-* } 307 }
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/58839.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/58839.cc
index 6ad2564..f78a07f 100644
--- a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/58839.cc
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/58839.cc
@@ -22,8 +22,12 @@ 
 
 // libstdc++/58839
 
+struct D {
+  void operator()(void*) const noexcept { }
+};
+
 void test01()
 {
-  std::unique_ptr<void> y;
+  std::unique_ptr<void, D> y;
   std::shared_ptr<void> x = std::move(y);
 }
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/void_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/void_neg.cc
new file mode 100644
index 0000000..3fd38cf
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/void_neg.cc
@@ -0,0 +1,29 @@ 
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+// Copyright (C) 2013 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.8.2.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+
+void test01()
+{
+  std::shared_ptr<void> p((void*)nullptr);   // { dg-error "here" }
+  // { dg-error "incomplete" "" { target *-*-* } 778 }
+}
diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/assign/48635_neg.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/assign/48635_neg.cc
index c785642..fdffafc 100644
--- a/libstdc++-v3/testsuite/20_util/unique_ptr/assign/48635_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/unique_ptr/assign/48635_neg.cc
@@ -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 *-*-* } 270 }
+// { dg-error "use of deleted function" "" { target *-*-* } 272 }
 
   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 *-*-* } 515 }
+// { dg-error "use of deleted function" "" { target *-*-* } 517 }
 }