changeset 32178:01ab19a0e2b9

Same destructor order in frame in std::vector for libstdc++ and libc++ (patch #10366). * libinterp/corefcn/stack-frame.cc (~base_value_stack_frame): The order in which elements of a std::vector are destroyed seems to be from back to front with libc++. It is from front to back with libstdc++. Explicitly overwrite the elements in the std::vector<octave_value> members from front to back when using libc++. That ensures that their destructors are called in the same order, e.g, for classdef objects.
author Petter T. <petter.vilhelm@gmail.com>
date Sun, 25 Jun 2023 00:56:43 +0200
parents 2c9f01dc9fb5
children 4b8df475bb5e
files libinterp/corefcn/stack-frame.cc
diffstat 1 files changed, 16 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/stack-frame.cc	Mon Jul 03 21:49:07 2023 +0200
+++ b/libinterp/corefcn/stack-frame.cc	Sun Jun 25 00:56:43 2023 +0200
@@ -1187,7 +1187,23 @@
   base_value_stack_frame&
   operator = (const base_value_stack_frame& elt) = delete;
 
+// LLVM libc++ has the opposite element dtor order compared to GNU libstdc++
+// for std::vector.  So, overwrite elements manually from first to last when
+// using LLVM libc++ to have identical dtor call order, e.g., for classdefs.
+#if defined (HAVE_LLVM_LIBCXX)
+  ~base_value_stack_frame ()
+  {
+    // Member dtor order is last to first.  So, m_auto_vars before m_values.
+
+    for (std::size_t i = 0; i < m_auto_vars.size (); i++)
+      m_auto_vars[i] = octave_value ();
+
+    for (std::size_t i = 0; i < m_values.size (); i++)
+      m_values[i] = octave_value ();
+  }
+#else
   ~base_value_stack_frame () = default;
+#endif
 
   std::size_t size () const
   {