]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Make type_stack pushing a bit safer
authorTom Tromey <tom@tromey.com>
Sat, 23 Aug 2025 17:39:35 +0000 (11:39 -0600)
committerTom Tromey <tom@tromey.com>
Wed, 10 Sep 2025 00:24:32 +0000 (18:24 -0600)
This changes type_stack to make pushing elements a bit safer: if an
element requires an argument, these are now always pushed at the same
time, rather than separately.

This patch also adds a few comments to help document a bit better.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
gdb/c-exp.y
gdb/d-exp.y
gdb/f-exp.y
gdb/type-stack.h

index 98be2da72342f59e55a205d474f7fe87150ae9dd..3abfafe4b525691bcbcc3d31cf7675da561eab8f 100644 (file)
@@ -1303,15 +1303,13 @@ direct_abs_decl: '(' abs_decl ')'
        |       direct_abs_decl array_mod
                        {
                          cpstate->type_stack.push ($1);
-                         cpstate->type_stack.push ($2);
-                         cpstate->type_stack.push (tp_array);
+                         cpstate->type_stack.push (tp_array, $2);
                          $$ = cpstate->type_stack.create ();
                          cpstate->type_stacks.emplace_back ($$);
                        }
        |       array_mod
                        {
-                         cpstate->type_stack.push ($1);
-                         cpstate->type_stack.push (tp_array);
+                         cpstate->type_stack.push (tp_array, $1);
                          $$ = cpstate->type_stack.create ();
                          cpstate->type_stacks.emplace_back ($$);
                        }
index 6b4fd048e6f1a9b456a79417b82d26ab677cfacb..e774dee844988df37d9f0816d298fa9a6761af0a 100644 (file)
@@ -613,11 +613,9 @@ BasicType2:
 |      '*' BasicType2
                { type_stack->push (tp_pointer); }
 |      '[' INTEGER_LITERAL ']'
-               { type_stack->push ($2.val);
-                 type_stack->push (tp_array); }
+               { type_stack->push (tp_array, $2.val); }
 |      '[' INTEGER_LITERAL ']' BasicType2
-               { type_stack->push ($2.val);
-                 type_stack->push (tp_array); }
+               { type_stack->push (tp_array, $2.val); }
 ;
 
 BasicType:
index 07fc54ca9a1c2226a76e5b5e04bdb30f50c9b1cc..a8ee9a361f9191df52463f2f29b83f09f20d8357 100644 (file)
@@ -1159,8 +1159,7 @@ push_kind_type (LONGEST val, struct type *type)
       ival = static_cast <int> (val);
     }
 
-  type_stack->push (ival);
-  type_stack->push (tp_kind);
+  type_stack->push (tp_kind, ival);
 }
 
 /* Helper function for convert_to_kind_type.  */
index af5a89d2feb63effef168cc1434a6bf6e76090f5..64940ddfc7750c1ed3e345923bff5bd095e6a73c 100644 (file)
 struct type;
 struct expr_builder;
 
-/* For parsing of complicated types.
-   An array should be preceded in the list by the size of the array.  */
+/* The kind of element on the stack of types and qualifiers, used for
+   parsing complicated types.  */
 enum type_pieces
-  {
-    tp_end = -1, 
-    tp_pointer, 
-    tp_reference, 
-    tp_rvalue_reference,
-    tp_array, 
-    tp_function,
-    tp_function_with_arguments,
-    tp_const, 
-    tp_volatile, 
-    tp_space_identifier,
-    tp_atomic,
-    tp_restrict,
-    tp_type_stack,
-    tp_kind
-  };
-
-/* The stack can contain either an enum type_pieces or an int.  */
+{
+  /* This is returned by pop() to indicate that the stack is empty.
+     Note that it may not be pushed by the user.  */
+  tp_end = -1,
+  tp_pointer,
+  tp_reference,
+  tp_rvalue_reference,
+  /* An array type, where the dimension is pushed on the stack as
+     well.  */
+  tp_array,
+  tp_function,
+  /* A function with argument types; the types are also pushed on the
+     stack.  */
+  tp_function_with_arguments,
+  tp_const,
+  tp_volatile,
+  /* An address space identifier.  The address space is also pushed on
+     the stack.  */
+  tp_space_identifier,
+  tp_atomic,
+  tp_restrict,
+  /* A separate type stack, which is also pushed onto this type
+     stack.  */
+  tp_type_stack,
+  /* Fortran-specific, specifies the kind.  */
+  tp_kind,
+};
+
+/* Items on the type stack.  */
 union type_stack_elt
-  {
-    enum type_pieces piece;
-    int int_val;
-    struct type_stack *stack_val;
-    std::vector<struct type *> *typelist_val;
-  };
+{
+  /* An ordinary type qualifier.  */
+  enum type_pieces piece;
+  /* An integer value.  Currently only used for address spaces.  */
+  int int_val;
+  /* Another type stack.  */
+  struct type_stack *stack_val;
+  /* A list of types.  */
+  std::vector<struct type *> *typelist_val;
+};
 
 /* The type stack is an instance of this structure.  */
 
@@ -80,18 +95,31 @@ public:
 
   void insert (enum type_pieces tp);
 
+  /* Push an ordinary element on the type stack.  This can be used for
+     any element that doesn't require any extra data.  */
   void push (enum type_pieces tp)
   {
+    /* tp_end can only be returned by this class, not pushed.  The
+       others require a payload on the stack and so can only be pushed
+       by the appropriate method.  */
+    gdb_assert (tp != tp_end);
+    gdb_assert (!requires_payload (tp));
     type_stack_elt elt;
     elt.piece = tp;
     m_elements.push_back (elt);
   }
 
-  void push (int n)
+  /* Push an element and an integer value onto the stack.  The integer
+     value is pushed first, followed by TP.  Only piece kinds that
+     accept an integer argument are allowed.  */
+  void push (enum type_pieces tp, int n)
   {
+    gdb_assert (tp == tp_array || tp == tp_space_identifier || tp == tp_kind);
     type_stack_elt elt;
     elt.int_val = n;
     m_elements.push_back (elt);
+    elt.piece = tp;
+    m_elements.push_back (elt);
   }
 
   /* Push the type stack STACK as an element on this type stack.  */
@@ -101,11 +129,12 @@ public:
     type_stack_elt elt;
     elt.stack_val = stack;
     m_elements.push_back (elt);
-    push (tp_type_stack);
+    elt.piece = tp_type_stack;
+    m_elements.push_back (elt);
   }
 
-  /* Push a function type with arguments onto the global type stack.
-     LIST holds the argument types.  If the final item in LIST is NULL,
+  /* Push a function type with arguments onto this type stack.  LIST
+     holds the argument types.  If the final item in LIST is NULL,
      then the function will be varargs.  */
 
   void push (std::vector<struct type *> *list)
@@ -113,7 +142,8 @@ public:
     type_stack_elt elt;
     elt.typelist_val = list;
     m_elements.push_back (elt);
-    push (tp_function_with_arguments);
+    elt.piece = tp_function_with_arguments;
+    m_elements.push_back (elt);
   }
 
   enum type_pieces pop ()
@@ -127,11 +157,7 @@ public:
 
   int pop_int ()
   {
-    if (m_elements.empty ())
-      {
-       /* "Can't happen".  */
-       return 0;
-      }
+    gdb_assert (!m_elements.empty ());
     type_stack_elt elt = m_elements.back ();
     m_elements.pop_back ();
     return elt.int_val;
@@ -198,6 +224,14 @@ private:
     m_elements.insert (m_elements.begin () + slot, element);
   }
 
+  /* Return true if TP requires some payload element.  */
+  bool requires_payload (type_pieces tp) const
+  {
+    return (tp == tp_array || tp == tp_kind || tp == tp_type_stack
+           || tp == tp_function_with_arguments
+           || tp == tp_space_identifier);
+  }
+
 
   /* Elements on the stack.  */
   std::vector<union type_stack_elt> m_elements;