aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2020-01-09 01:39:45 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2020-01-09 01:39:45 +0000
commite4d2203e31e7c017266e61dbf0d24ee85e59fa55 (patch)
tree280fe13e89a65db7d5867eceacee2ae31f26afda /gcc
parentb3de347f3296995eb2a648d6303ab66bf689e104 (diff)
downloadgcc-e4d2203e31e7c017266e61dbf0d24ee85e59fa55.zip
gcc-e4d2203e31e7c017266e61dbf0d24ee85e59fa55.tar.gz
gcc-e4d2203e31e7c017266e61dbf0d24ee85e59fa55.tar.bz2
vec.h: add auto_delete_vec
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/vec.c27
-rw-r--r--gcc/vec.h38
3 files changed, 73 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4c6e926..dae2741 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,13 @@
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.
2020-01-08 Jim Wilson <jimw@sifive.com>
diff --git a/gcc/vec.c b/gcc/vec.c
index 0056dd0..1c4b958 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 c230189..bd7c7351 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. */