]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Make type_stack popping a bit safer
authorTom Tromey <tom@tromey.com>
Sat, 23 Aug 2025 17:46:48 +0000 (11:46 -0600)
committerTom Tromey <tom@tromey.com>
Wed, 10 Sep 2025 00:24:32 +0000 (18:24 -0600)
This changes type_stack so that an element that has an argument can't
be popped in isolation.  The idea is to make type stack use a little
safer, making it so that the stack can't end up in an invalid state.

This also fixes up a few related comments.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
gdb/type-stack.h

index 64940ddfc7750c1ed3e345923bff5bd095e6a73c..f94e5262fb46c052d0bbd58ce63a3e407014264f 100644 (file)
@@ -146,28 +146,47 @@ public:
     m_elements.push_back (elt);
   }
 
+  /* Pop the topmost element of the stack and return it.
+
+     If the stack is empty, tp_end is returned.
+
+     If the topmost element requires a payload -- for example,
+     tp_array takes an integer parameter -- then the value is returned
+     but *not* popped from the stack.  Instead the appropriate
+     payload-specific pop_* method (e.g., pop_int) must then be
+     called.  This somewhat odd approach ensures that the stack can't
+     be put into an invalid state.  */
   enum type_pieces pop ()
   {
     if (m_elements.empty ())
       return tp_end;
     type_stack_elt elt = m_elements.back ();
-    m_elements.pop_back ();
+    if (!requires_payload (elt.piece))
+      m_elements.pop_back ();
     return elt.piece;
   }
 
   int pop_int ()
   {
-    gdb_assert (!m_elements.empty ());
+    gdb_assert (m_elements.size () >= 2);
     type_stack_elt elt = m_elements.back ();
     m_elements.pop_back ();
+    type_pieces tp = elt.piece;
+    gdb_assert (tp == tp_array || tp == tp_space_identifier || tp == tp_kind);
+    elt = m_elements.back ();
+    m_elements.pop_back ();
     return elt.int_val;
   }
 
   std::vector<struct type *> *pop_typelist ()
   {
-    gdb_assert (!m_elements.empty ());
+    gdb_assert (m_elements.size () >= 2);
     type_stack_elt elt = m_elements.back ();
     m_elements.pop_back ();
+    type_pieces tp = elt.piece;
+    gdb_assert (tp == tp_function_with_arguments);
+    elt = m_elements.back ();
+    m_elements.pop_back ();
     return elt.typelist_val;
   }
 
@@ -175,9 +194,13 @@ public:
 
   struct type_stack *pop_type_stack ()
   {
-    gdb_assert (!m_elements.empty ());
+    gdb_assert (m_elements.size () >= 2);
     type_stack_elt elt = m_elements.back ();
     m_elements.pop_back ();
+    type_pieces tp = elt.piece;
+    gdb_assert (tp == tp_type_stack);
+    elt = m_elements.back ();
+    m_elements.pop_back ();
     return elt.stack_val;
   }
 
@@ -214,9 +237,9 @@ public:
 
 private:
 
-  /* A helper function for insert_type and insert_type_address_space.
-     This does work of expanding the type stack and inserting the new
-     element, ELEMENT, into the stack at location SLOT.  */
+  /* A helper function for the insert methods.  This does work of
+     expanding the type stack and inserting the new element, ELEMENT,
+     into the stack at location SLOT.  */
 
   void insert_into (int slot, union type_stack_elt element)
   {