From e4d2203e31e7c017266e61dbf0d24ee85e59fa55 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 9 Jan 2020 01:39:45 +0000 Subject: [PATCH] vec.h: add auto_delete_vec This patch adds a class auto_delete_vec, a subclass of auto_vec 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::~auto_delete_vec): New dtor. From-SVN: r280027 --- gcc/ChangeLog | 8 ++++++++ gcc/vec.c | 27 +++++++++++++++++++++++++++ gcc/vec.h | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4c6e926d93f..dae2741ef20 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2020-01-08 David Malcolm + + * 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::~auto_delete_vec): New dtor. + 2020-01-08 David Malcolm * sbitmap.h (auto_sbitmap): Add operator const_sbitmap. diff --git a/gcc/vec.c b/gcc/vec.c index 0056dd0af94..1c4b958871b 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 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 c230189f404..bd7c7351dcd 100644 --- a/gcc/vec.h +++ b/gcc/vec.h @@ -1547,6 +1547,31 @@ class auto_string_vec : public auto_vec ~auto_string_vec (); }; +/* A subclass of auto_vec 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 +class auto_delete_vec : public auto_vec +{ + public: + auto_delete_vec () {} + auto_delete_vec (size_t s) : auto_vec (s) {} + + ~auto_delete_vec (); + +private: + DISABLE_COPY_AND_ASSIGN(auto_delete_vec); +}; + /* Conditionally allocate heap memory for VEC and its internal vector. */ template @@ -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 , which frees the internal buffer. */ + +template +inline +auto_delete_vec::~auto_delete_vec () +{ + int i; + T *item; + FOR_EACH_VEC_ELT (*this, i, item) + delete item; +} + /* Return a copy of this vector. */ -- 2.30.2