diff mbox series

[07/45] vec.h: add auto_delete_vec

Message ID 20191213181134.1830-8-dmalcolm@redhat.com
State New
Headers show
Series v4 of analyzer patch kit | expand

Commit Message

David Malcolm Dec. 13, 2019, 6:10 p.m. UTC
Changed in v4: added DISABLE_COPY_AND_ASSIGN

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 later in the 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.
---
 gcc/vec.c | 27 +++++++++++++++++++++++++++
 gcc/vec.h | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+)
diff mbox series

Patch

diff --git a/gcc/vec.c b/gcc/vec.c
index bac5eb753a3c..a9c840de00a0 100644
--- 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
diff --git a/gcc/vec.h b/gcc/vec.h
index 8070021223a6..cebc16ec68c4 100644
--- 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.  */