aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@gcc.gnu.org>2017-10-16 20:50:40 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2017-10-16 20:50:40 +0000
commit46d2b77d71c3c9a2ea326ae9c3a89a19de3254ca (patch)
treee11b3eda93410442b9c1c59e85c5147392d1728b /gcc
parent2de3d3c6a62ac4299e9f5a310e4bf8ff28dbd47f (diff)
downloadgcc-46d2b77d71c3c9a2ea326ae9c3a89a19de3254ca.zip
gcc-46d2b77d71c3c9a2ea326ae9c3a89a19de3254ca.tar.gz
gcc-46d2b77d71c3c9a2ea326ae9c3a89a19de3254ca.tar.bz2
Add gnu::unique_ptr
This is a version of the patch posted by Trevor Saunders on 2017-07-31, for which he wrote: > For most of the history of this see > https://sourceware.org/ml/gdb-patches/2016-10/msg00223.html > The changes are mostly s/gdb/gtl/g This version was updated by me (dmalcolm) adding these changes: - renaming of "gtl" to "gnu" (3 letters, and one of the ones Richi proposed, and not a match for "*tl") - renaming of DEFINE_GDB_UNIQUE_PTR to DEFINE_GNU_UNIQUE_PTR - renaming of xfree_deleter to xmalloc_deleter, and making it use "free" rather than "xfree" (which doesn't exist) - added a gcc/unique-ptr-tests.cc - implement unique_xmalloc_ptr<T[]> (taken from gdb, but changing "xfree" to "free", and adding support for pre-C++-11) gcc/ChangeLog: David Malcolm <dmalcolm@redhat.com> * Makefile.in (OBJS): Add unique-ptr-tests.o. * selftest-run-tests.c (selftest::run_tests): Call selftest::unique_ptr_tests_cc_tests. * selftest.h (selftest::unique_ptr_tests_cc_tests): New decl. * unique-ptr-tests.cc: New file. include/ChangeLog: Trevor Saunders <tbsaunde+gcc@tbsaunde.org> David Malcolm <dmalcolm@redhat.com> * unique-ptr.h: New file. From-SVN: r253797
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/Makefile.in1
-rw-r--r--gcc/selftest-run-tests.c1
-rw-r--r--gcc/selftest.h1
-rw-r--r--gcc/unique-ptr-tests.cc234
5 files changed, 245 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1814910..933e4e9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2017-10-16 David Malcolm <dmalcolm@redhat.com>
+
+ * Makefile.in (OBJS): Add unique-ptr-tests.o.
+ * selftest-run-tests.c (selftest::run_tests): Call
+ selftest::unique_ptr_tests_cc_tests.
+ * selftest.h (selftest::unique_ptr_tests_cc_tests): New decl.
+ * unique-ptr-tests.cc: New file.
+
2017-10-16 Vladimir Makarov <vmakarov@redhat.com>
PR sanitizer/82353
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 878ce7b..2809619 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1568,6 +1568,7 @@ OBJS = \
tree-vrp.o \
tree.o \
typed-splay-tree.o \
+ unique-ptr-tests.o \
valtrack.o \
value-prof.o \
var-tracking.o \
diff --git a/gcc/selftest-run-tests.c b/gcc/selftest-run-tests.c
index 5c84f3a..11bf0cc 100644
--- a/gcc/selftest-run-tests.c
+++ b/gcc/selftest-run-tests.c
@@ -67,6 +67,7 @@ selftest::run_tests ()
sreal_c_tests ();
fibonacci_heap_c_tests ();
typed_splay_tree_c_tests ();
+ unique_ptr_tests_cc_tests ();
/* Mid-level data structures. */
input_c_tests ();
diff --git a/gcc/selftest.h b/gcc/selftest.h
index 2e649a7..6478922 100644
--- a/gcc/selftest.h
+++ b/gcc/selftest.h
@@ -195,6 +195,7 @@ extern void store_merging_c_tests ();
extern void typed_splay_tree_c_tests ();
extern void tree_c_tests ();
extern void tree_cfg_c_tests ();
+extern void unique_ptr_tests_cc_tests ();
extern void vec_c_tests ();
extern void wide_int_cc_tests ();
extern void predict_c_tests ();
diff --git a/gcc/unique-ptr-tests.cc b/gcc/unique-ptr-tests.cc
new file mode 100644
index 0000000..f5b72a8
--- /dev/null
+++ b/gcc/unique-ptr-tests.cc
@@ -0,0 +1,234 @@
+/* Unit tests for unique-ptr.h.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC 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.
+
+GCC 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 GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "unique-ptr.h"
+#include "selftest.h"
+
+#if CHECKING_P
+
+namespace selftest {
+
+namespace {
+
+/* A class for counting ctor and dtor invocations. */
+
+struct stats
+{
+ stats () : ctor_count (0), dtor_count (0) {}
+
+ int ctor_count;
+ int dtor_count;
+};
+
+/* A class that uses "stats" to track its ctor and dtor invocations. */
+
+class foo
+{
+public:
+ foo (stats &s) : m_s (s) { ++m_s.ctor_count; }
+ ~foo () { ++m_s.dtor_count; }
+
+ int example_method () const { return 42; }
+
+private:
+ foo (const foo&);
+ foo & operator= (const foo &);
+
+private:
+ stats &m_s;
+};
+
+/* A struct for testing unique_ptr<T[]>. */
+
+struct has_default_ctor
+{
+ has_default_ctor () : m_field (42) {}
+ int m_field;
+};
+
+/* A dummy struct for testing unique_xmalloc_ptr. */
+
+struct dummy
+{
+ int field;
+};
+
+} // anonymous namespace
+
+/* Verify that the default ctor inits ptrs to NULL. */
+
+static void
+test_null_ptr ()
+{
+ gnu::unique_ptr<void *> p;
+ ASSERT_EQ (NULL, p);
+
+ gnu::unique_xmalloc_ptr<void *> q;
+ ASSERT_EQ (NULL, q);
+}
+
+/* Verify that deletion happens when a unique_ptr goes out of scope. */
+
+static void
+test_implicit_deletion ()
+{
+ stats s;
+ ASSERT_EQ (0, s.ctor_count);
+ ASSERT_EQ (0, s.dtor_count);
+
+ {
+ gnu::unique_ptr<foo> f (new foo (s));
+ ASSERT_NE (NULL, f);
+ ASSERT_EQ (1, s.ctor_count);
+ ASSERT_EQ (0, s.dtor_count);
+ }
+
+ /* Verify that the foo was implicitly deleted. */
+ ASSERT_EQ (1, s.ctor_count);
+ ASSERT_EQ (1, s.dtor_count);
+}
+
+/* Verify that we can assign to a NULL unique_ptr. */
+
+static void
+test_overwrite_of_null ()
+{
+ stats s;
+ ASSERT_EQ (0, s.ctor_count);
+ ASSERT_EQ (0, s.dtor_count);
+
+ {
+ gnu::unique_ptr<foo> f;
+ ASSERT_EQ (NULL, f);
+ ASSERT_EQ (0, s.ctor_count);
+ ASSERT_EQ (0, s.dtor_count);
+
+ /* Overwrite with a non-NULL value. */
+ f = gnu::unique_ptr<foo> (new foo (s));
+ ASSERT_EQ (1, s.ctor_count);
+ ASSERT_EQ (0, s.dtor_count);
+ }
+
+ /* Verify that the foo is implicitly deleted. */
+ ASSERT_EQ (1, s.ctor_count);
+ ASSERT_EQ (1, s.dtor_count);
+}
+
+/* Verify that we can assign to a non-NULL unique_ptr. */
+
+static void
+test_overwrite_of_non_null ()
+{
+ stats s;
+ ASSERT_EQ (0, s.ctor_count);
+ ASSERT_EQ (0, s.dtor_count);
+
+ {
+ gnu::unique_ptr<foo> f (new foo (s));
+ ASSERT_NE (NULL, f);
+ ASSERT_EQ (1, s.ctor_count);
+ ASSERT_EQ (0, s.dtor_count);
+
+ /* Overwrite with a different value. */
+ f = gnu::unique_ptr<foo> (new foo (s));
+ ASSERT_EQ (2, s.ctor_count);
+ ASSERT_EQ (1, s.dtor_count);
+ }
+
+ /* Verify that the 2nd foo was implicitly deleted. */
+ ASSERT_EQ (2, s.ctor_count);
+ ASSERT_EQ (2, s.dtor_count);
+}
+
+/* Verify that unique_ptr's overloaded ops work. */
+
+static void
+test_overloaded_ops ()
+{
+ stats s;
+ gnu::unique_ptr<foo> f (new foo (s));
+ ASSERT_EQ (42, f->example_method ());
+ ASSERT_EQ (42, (*f).example_method ());
+ ASSERT_EQ (f, f);
+ ASSERT_NE (NULL, f.get ());
+
+ gnu::unique_ptr<foo> g (new foo (s));
+ ASSERT_NE (f, g);
+}
+
+/* Verify that the gnu::unique_ptr specialization for T[] works. */
+
+static void
+test_array_new ()
+{
+ const int num = 10;
+ gnu::unique_ptr<has_default_ctor[]> p (new has_default_ctor[num]);
+ ASSERT_NE (NULL, p.get ());
+ /* Verify that operator[] works, and that the default ctor was called
+ on each element. */
+ for (int i = 0; i < num; i++)
+ ASSERT_EQ (42, p[i].m_field);
+}
+
+/* Verify that gnu::unique_xmalloc_ptr works. */
+
+static void
+test_xmalloc ()
+{
+ gnu::unique_xmalloc_ptr<dummy> p (XNEW (dummy));
+ ASSERT_NE (NULL, p.get ());
+}
+
+/* Verify the gnu::unique_xmalloc_ptr specialization for T[]. */
+
+static void
+test_xmalloc_array ()
+{
+ const int num = 10;
+ gnu::unique_xmalloc_ptr<dummy[]> p (XNEWVEC (dummy, num));
+ ASSERT_NE (NULL, p.get ());
+
+ /* Verify that operator[] works. */
+ for (int i = 0; i < num; i++)
+ p[i].field = 42;
+ for (int i = 0; i < num; i++)
+ ASSERT_EQ (42, p[i].field);
+}
+
+/* Run all of the selftests within this file. */
+
+void
+unique_ptr_tests_cc_tests ()
+{
+ test_null_ptr ();
+ test_implicit_deletion ();
+ test_overwrite_of_null ();
+ test_overwrite_of_non_null ();
+ test_overloaded_ops ();
+ test_array_new ();
+ test_xmalloc ();
+ test_xmalloc_array ();
+}
+
+} // namespace selftest
+
+#endif /* #if CHECKING_P */