Make type_stack popping a bit safer

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>
This commit is contained in:
Tom Tromey
2025-08-23 11:46:48 -06:00
parent 8ea36fc9f3
commit c152f17e36

View File

@@ -146,28 +146,47 @@ public:
m_elements.push_back (elt); 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 () enum type_pieces pop ()
{ {
if (m_elements.empty ()) if (m_elements.empty ())
return tp_end; return tp_end;
type_stack_elt elt = m_elements.back (); type_stack_elt elt = m_elements.back ();
m_elements.pop_back (); if (!requires_payload (elt.piece))
m_elements.pop_back ();
return elt.piece; return elt.piece;
} }
int pop_int () int pop_int ()
{ {
gdb_assert (!m_elements.empty ()); gdb_assert (m_elements.size () >= 2);
type_stack_elt elt = m_elements.back (); type_stack_elt elt = m_elements.back ();
m_elements.pop_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; return elt.int_val;
} }
std::vector<struct type *> *pop_typelist () std::vector<struct type *> *pop_typelist ()
{ {
gdb_assert (!m_elements.empty ()); gdb_assert (m_elements.size () >= 2);
type_stack_elt elt = m_elements.back (); type_stack_elt elt = m_elements.back ();
m_elements.pop_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; return elt.typelist_val;
} }
@@ -175,9 +194,13 @@ public:
struct type_stack *pop_type_stack () struct type_stack *pop_type_stack ()
{ {
gdb_assert (!m_elements.empty ()); gdb_assert (m_elements.size () >= 2);
type_stack_elt elt = m_elements.back (); type_stack_elt elt = m_elements.back ();
m_elements.pop_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; return elt.stack_val;
} }
@@ -214,9 +237,9 @@ public:
private: private:
/* A helper function for insert_type and insert_type_address_space. /* A helper function for the insert methods. This does work of
This does work of expanding the type stack and inserting the new expanding the type stack and inserting the new element, ELEMENT,
element, ELEMENT, into the stack at location SLOT. */ into the stack at location SLOT. */
void insert_into (int slot, union type_stack_elt element) void insert_into (int slot, union type_stack_elt element)
{ {