From: Tom Tromey Date: Sat, 23 Aug 2025 17:39:35 +0000 (-0600) Subject: Make type_stack pushing a bit safer X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8ea36fc9f314e9de921044883457085b57c16045;p=thirdparty%2Fbinutils-gdb.git Make type_stack pushing a bit safer 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 --- diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 98be2da7234..3abfafe4b52 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -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 ($$); } diff --git a/gdb/d-exp.y b/gdb/d-exp.y index 6b4fd048e6f..e774dee8449 100644 --- a/gdb/d-exp.y +++ b/gdb/d-exp.y @@ -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: diff --git a/gdb/f-exp.y b/gdb/f-exp.y index 07fc54ca9a1..a8ee9a361f9 100644 --- a/gdb/f-exp.y +++ b/gdb/f-exp.y @@ -1159,8 +1159,7 @@ push_kind_type (LONGEST val, struct type *type) ival = static_cast (val); } - type_stack->push (ival); - type_stack->push (tp_kind); + type_stack->push (tp_kind, ival); } /* Helper function for convert_to_kind_type. */ diff --git a/gdb/type-stack.h b/gdb/type-stack.h index af5a89d2feb..64940ddfc77 100644 --- a/gdb/type-stack.h +++ b/gdb/type-stack.h @@ -26,34 +26,49 @@ 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 *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 *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 *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 m_elements;