When running with target board cc-with-dwz, I run into: ... (gdb) print enum_with_gaps'enum_rep(lit3)^M 'Enum_Rep requires argument to have same type as enum^M (gdb) FAIL: gdb.ada/arr_acc_idx_w_gap.exp: enum_rep ... With target_board unix, we have instead: ... (gdb) PASS: gdb.ada/arr_acc_idx_w_gap.exp: print s(2) print enum_with_gaps'enum_rep(lit3)^M $16 = 13^M (gdb) PASS: gdb.ada/arr_acc_idx_w_gap.exp: enum_rep ... The error happens here: ... 8828 if (!types_equal (type, arg->type ())) 8829 error (_("'Enum_Rep requires argument to have same type as enum")); ... because these types are not considered equal: ... (gdb) p type->name () $1 = 0x7fffe4673e7d "enum_with_gap__enum_with_gaps" (gdb) p arg->type()->name () $2 = 0x7fffe467411f "enum_with_gap__enum_subrangeB" ... With target_board_unix, we have instead: ... (gdb) p type->name () $1 = 0x7fffcc666c2d "enum_with_gap__enum_with_gaps" (gdb) p arg->type()->name () $2 = 0x7fffcc666c2d "enum_with_gap__enum_with_gaps" ...
With target board unix, looking at the debug info we have: ... <0><81c>: Abbrev Number: 1 (DW_TAG_compile_unit) <822> DW_AT_name : enum_with_gap.adb <1><84c>: Abbrev Number: 4 (DW_TAG_enumeration_type) <84d> DW_AT_name : enum_with_gap__enum_with_gaps <2><86b>: Abbrev Number: 5 (DW_TAG_enumerator) <86c> DW_AT_name : enum_with_gap__lit3 <870> DW_AT_const_value : 13 <0><9e9>: Abbrev Number: 1 (DW_TAG_compile_unit) <9ef> DW_AT_name : enum_with_gap_main.adb <1><a20>: Abbrev Number: 4 (DW_TAG_enumeration_type) <a21> DW_AT_name : enum_with_gap__enum_with_gaps <2><a3f>: Abbrev Number: 5 (DW_TAG_enumerator) <a40> DW_AT_name : enum_with_gap__lit3 <a44> DW_AT_const_value : 13 <1><b4c>: Abbrev Number: 16 (DW_TAG_enumeration_type) <b4d> DW_AT_name : enum_with_gap__enum_subrangeB <b55> DW_AT_artificial : 1 <2><b6b>: Abbrev Number: 5 (DW_TAG_enumerator) <b6c> DW_AT_name : enum_with_gap__lit3__2 <b70> DW_AT_const_value : 13 ... Dwz moves enum_with_gap__enum_with_gaps into a partial unit. That somehow changes the symbol table. With target board unix, the first item with canonical name lit3 is: ... [721] ((cooked_index_entry *) 0x7fe8d8009b00) name: enum_with_gap__lit3 canonical: lit3 DWARF tag: DW_TAG_enumerator flags: 0x2 [IS_STATIC] DIE offset: 0x86b parent: ((cooked_index_entry *) 0x7fe8d8021fe0) [enum_with_gap] ... With target board cc-with-dwz, it's instead: ... [780] ((cooked_index_entry *) 0x7f9d1c0049c0) name: enum_with_gap__lit3__2 canonical: lit3 DWARF tag: DW_TAG_enumerator flags: 0x2 [IS_STATIC] DIE offset: 0x23a5 parent: ((cooked_index_entry *) 0x7f9d1c025ad0) [enum_with_gap] ...
Created attachment 15042 [details] enum_with_gap_main.gz (stripped with --only-keep-debug) $ gdb -q -batch ./enum_with_gap_main -ex "print enum_with_gaps'enum_rep(lit3)" 'Enum_Rep requires argument to have same type as enum This is with gcc 12, analysis above done with gcc 7.
Also fails with target board debug-types.
Fixed by: ... diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index c0cc512bfa3..5b8b54331b7 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -5104,7 +5104,8 @@ remove_extra_symbols (std::vector<struct block_symbol> &syms) to ask the user to disambiguate anyways. And if we have to present a multiple-choice menu, it's less confusing if the list isn't missing some choices that were identical and yet distinct. */ - if (symbols_are_identical_enums (syms)) + if (false && symbols_are_identical_enums (syms)) syms.resize (1); } ... Here in remove_extra_symbols we randomly throw away one of the two enums. In the cc-with-dwz variant, we throw away the wrong one because the order in which the symbols is found has changed. If there are two symbols remaining after remove_extra_symbols, write_var_or_type produces an ambiguous var, which then allows the ada_pop here: ... | type_prefix TICK_ENUM_REP '(' exp ')' { operation_up arg = ada_pop (true, $1); pstate->push_new<ada_atr_enum_rep_operation> ($1, std::move (arg)); } ... to resolve the literal using the $1 context_type.
Reproduces with target board unix: ... diff --git a/gdb/testsuite/gdb.ada/arr_acc_idx_w_gap.exp b/gdb/testsuite/gdb.ada/arr_acc_idx_w_gap.exp index 4a1482b6d99..a98e9e1e2c3 100644 --- a/gdb/testsuite/gdb.ada/arr_acc_idx_w_gap.exp +++ b/gdb/testsuite/gdb.ada/arr_acc_idx_w_gap.exp @@ -69,6 +69,8 @@ foreach_with_prefix scenario {all minimal} { gdb_test "print enum_with_gaps'enum_rep(lit3)" " = 13" \ "enum_rep" + gdb_test "print enum_subrange'enum_rep(lit3)" " = 13" \ + "other enum_rep" gdb_test "print enum_with_gaps'enum_val(21)" " = lit4" \ "enum_val" } ... Dropping the cc-with-dwz from $summary.
(In reply to Tom de Vries from comment #4) > Fixed by: Well, in the sense that we have: ... $ gdb -q -batch ./enum_with_gap_main-all -ex "print enum_with_gaps'enum_rep(lit3)" $1 = 13 $ gdb -q -batch ./enum_with_gap_main-all -ex "print enum_subrange'enum_rep(lit3)" $1 = 13 $ gdb -q -batch ./enum_with_gap_main-all.dwz -ex "print enum_with_gaps'enum_rep(lit3)" $1 = 13 $ gdb -q -batch ./enum_with_gap_main-all.dwz -ex "print enum_subrange'enum_rep(lit3)" $1 = 13 ... When running the test-case, we run into the unsurprising fallout: ... (gdb) print indexed_by_enum(lit2..lit4)^M Multiple matches for lit4^M [0] cancel^M [1] enum_with_gap.enum_with_gaps'(enum_with_gap.lit4) (enumeral)^M [2] enum_with_gap.enum_subrangeB'(enum_with_gap.lit4) (enumeral)^M > FAIL: gdb.ada/arr_acc_idx_w_gap.exp: scenario=all: print indexed_by_enum(lit2..lit4) (timeout) ... Interestingly, the test-case that is supposed to fail is passing because the compiler drops an unused type, this fixes that: ... diff --git a/gdb/testsuite/gdb.ada/same_enum/a.adb b/gdb/testsuite/gdb.ada/same_enum/a.adb index ef2cceb3e60..4612aaa7283 100644 --- a/gdb/testsuite/gdb.ada/same_enum/a.adb +++ b/gdb/testsuite/gdb.ada/same_enum/a.adb @@ -17,7 +17,7 @@ with Pck; use Pck; procedure A is FC : Color := Red; - SC : Color := Green; + SC : RGB_Color := Green; begin Do_Nothing (FC'Address); Do_Nothing (SC'Address); ... Anyway, the fallout is limited to gdb.ada/arr_acc_idx_w_gap.exp and the fixed gdb.ada/same_enum.exp test-cases, all other test-cases pass.
(In reply to Tom de Vries from comment #6) > - SC : Color := Green; > + SC : RGB_Color := Green; Committed here ( https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=313b2841b8e9046ea658104988e01bedf6148d5f ).
Created attachment 15100 [details] tentative patch
https://sourceware.org/pipermail/gdb-patches/2023-September/202188.html
The master branch has been updated by Tom de Vries <vries@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ef136c7fa165cf3ee75c37d41561be8a7bdc89bd commit ef136c7fa165cf3ee75c37d41561be8a7bdc89bd Author: Tom de Vries <tdevries@suse.de> Date: Thu Sep 7 21:39:42 2023 +0200 [gdb/ada] Move identical enums handling later When running test-case gdb.ada/arr_acc_idx_w_gap.exp with target board cc-with-dwz, I run into: ... (gdb) print enum_with_gaps'enum_rep(lit3)^M 'Enum_Rep requires argument to have same type as enum^M (gdb) FAIL: gdb.ada/arr_acc_idx_w_gap.exp: enum_rep ... With target_board unix, we have instead: ... (gdb) print enum_with_gaps'enum_rep(lit3)^M $16 = 13^M (gdb) PASS: gdb.ada/arr_acc_idx_w_gap.exp: enum_rep ... Conversely, when I add this test to the test-case: ... gdb_test "print enum_with_gaps'enum_rep(lit3)" " = 13" \ "enum_rep" + gdb_test "print enum_subrange'enum_rep(lit3)" " = 13" \ + "other enum_rep" ... the extra test passes with target board cc-with-dwz, but fails with target board unix. The problem is here in remove_extra_symbols: ... if (symbols_are_identical_enums (syms)) syms.resize (1); ... where one of the two identical enums is picked before the enum_rep handling can resolve lit3 to one of the two. Fix this by moving the code to ada_resolve_variable. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com> PR ada/30726 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30726
Fixed.