]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
vec.h: add auto_delete_vec
authorDavid Malcolm <dmalcolm@redhat.com>
Thu, 9 Jan 2020 01:39:45 +0000 (01:39 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Thu, 9 Jan 2020 01:39:45 +0000 (01:39 +0000)
This patch adds a class auto_delete_vec<T>, a subclass of auto_vec <T *>
that deletes all of its elements on destruction; it's used in many
places in the analyzer patch kit.

This is a crude way for a vec to "own" the objects it points to
and clean up automatically (essentially a workaround for not being able
to use unique_ptr, due to C++98).

gcc/ChangeLog:
* vec.c (class selftest::count_dtor): New class.
(selftest::test_auto_delete_vec): New test.
(selftest::vec_c_tests): Call it.
* vec.h (class auto_delete_vec): New class template.
(auto_delete_vec<T>::~auto_delete_vec): New dtor.

From-SVN: r280027

gcc/ChangeLog
gcc/vec.c
gcc/vec.h

index 4c6e926d93f37987cd4f30bbb83ed82d888caadf..dae2741ef20092be1698f4eb306c099417cfadd7 100644 (file)
@@ -1,3 +1,11 @@
+2020-01-08  David Malcolm  <dmalcolm@redhat.com>
+
+       * vec.c (class selftest::count_dtor): New class.
+       (selftest::test_auto_delete_vec): New test.
+       (selftest::vec_c_tests): Call it.
+       * vec.h (class auto_delete_vec): New class template.
+       (auto_delete_vec<T>::~auto_delete_vec): New dtor.
+
 2020-01-08  David Malcolm  <dmalcolm@redhat.com>
 
        * sbitmap.h (auto_sbitmap): Add operator const_sbitmap.
index 0056dd0af942225910d1f272b5877a3307c746d3..1c4b958871b474da0a98b8695d9fb3f134fa2426 100644 (file)
--- a/gcc/vec.c
+++ b/gcc/vec.c
@@ -516,6 +516,32 @@ test_reverse ()
   }
 }
 
+/* A test class that increments a counter every time its dtor is called.  */
+
+class count_dtor
+{
+ public:
+  count_dtor (int *counter) : m_counter (counter) {}
+  ~count_dtor () { (*m_counter)++; }
+
+ private:
+  int *m_counter;
+};
+
+/* Verify that auto_delete_vec deletes the elements within it.  */
+
+static void
+test_auto_delete_vec ()
+{
+  int dtor_count = 0;
+  {
+    auto_delete_vec <count_dtor> v;
+    v.safe_push (new count_dtor (&dtor_count));
+    v.safe_push (new count_dtor (&dtor_count));
+  }
+  ASSERT_EQ (dtor_count, 2);
+}
+
 /* Run all of the selftests within this file.  */
 
 void
@@ -533,6 +559,7 @@ vec_c_tests ()
   test_block_remove ();
   test_qsort ();
   test_reverse ();
+  test_auto_delete_vec ();
 }
 
 } // namespace selftest
index c230189f4048741d7c7d576f40e00301d38e1ccd..bd7c7351dcd98c0809956de5511a52d318f74723 100644 (file)
--- a/gcc/vec.h
+++ b/gcc/vec.h
@@ -1547,6 +1547,31 @@ class auto_string_vec : public auto_vec <char *>
   ~auto_string_vec ();
 };
 
+/* A subclass of auto_vec <T *> that deletes all of its elements on
+   destruction.
+
+   This is a crude way for a vec to "own" the objects it points to
+   and clean up automatically.
+
+   For example, no attempt is made to delete elements when an item
+   within the vec is overwritten.
+
+   We can't rely on gnu::unique_ptr within a container,
+   since we can't rely on move semantics in C++98.  */
+
+template <typename T>
+class auto_delete_vec : public auto_vec <T *>
+{
+ public:
+  auto_delete_vec () {}
+  auto_delete_vec (size_t s) : auto_vec <T *> (s) {}
+
+  ~auto_delete_vec ();
+
+private:
+  DISABLE_COPY_AND_ASSIGN(auto_delete_vec<T>);
+};
+
 /* Conditionally allocate heap memory for VEC and its internal vector.  */
 
 template<typename T>
@@ -1651,6 +1676,19 @@ auto_string_vec::~auto_string_vec ()
     free (str);
 }
 
+/* auto_delete_vec's dtor, deleting all contained items, automatically
+   chaining up to ~auto_vec <T*>, which frees the internal buffer.  */
+
+template <typename T>
+inline
+auto_delete_vec<T>::~auto_delete_vec ()
+{
+  int i;
+  T *item;
+  FOR_EACH_VEC_ELT (*this, i, item)
+    delete item;
+}
+
 
 /* Return a copy of this vector.  */