Bug 25889

Summary: [debug-types] FAIL: gdb.cp/cpexprs.exp: list policy1::function
Product: gdb Reporter: Tom de Vries <vries>
Component: symtabAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P2    
Version: HEAD   
Target Milestone: 10.1   
Host: Target:
Build: Last reconfirmed:

Description Tom de Vries 2020-04-28 17:34:11 UTC
I did a test run with target board debug-types, with and without commit 770479f223e "gdb: Fix toplevel types with -fdebug-types-section".

Overall results are good:
...
                === gdb Summary ===
 
-# of expected passes           76747
+# of expected passes           78636
-# of unexpected failures       1916
+# of unexpected failures       68
-# of expected failures         131
+# of expected failures         130
-# of known failures            74
+# of known failures            72
 # of unresolved testcases      22
 # of untested testcases                37
 # of unsupported tests         83
...

But, there are some regressions:
...
$ diff -u base/gdb.sum patched/gdb.sum \
  | grep '^\+' \
  | egrep -v "^\+(PASS|KFAIL):"
+FAIL: gdb.cp/cpexprs.exp: list policy1::function
+FAIL: gdb.cp/cpexprs.exp: list policy2::function
+FAIL: gdb.cp/cpexprs.exp: list policy3::function
+FAIL: gdb.cp/cpexprs.exp: list policy4::function
+FAIL: gdb.cp/cpexprs.exp: list policyd1::function
+FAIL: gdb.cp/cpexprs.exp: list policyd2::function
+FAIL: gdb.cp/cpexprs.exp: list policyd3::function
+FAIL: gdb.cp/cpexprs.exp: list policyd4::function
+FAIL: gdb.cp/cpexprs.exp: list policyd5::function
+FAIL: gdb.cp/cpexprs.exp: list policyd<base, operation_1<base> >::function
+FAIL: gdb.cp/cpexprs.exp: list policyd<char, operation_1<char> >::function
+FAIL: gdb.cp/cpexprs.exp: list policyd<int, operation_1<int> >::function
+FAIL: gdb.cp/cpexprs.exp: list policyd<tclass<int>, operation_1<tclass<int> > >::function
+FAIL: gdb.cp/cpexprs.exp: setting breakpoint at policy1::function
+FAIL: gdb.cp/cpexprs.exp: setting breakpoint at policy2::function
+FAIL: gdb.cp/cpexprs.exp: setting breakpoint at policy3::function
+FAIL: gdb.cp/cpexprs.exp: setting breakpoint at policy4::function
+FAIL: gdb.cp/cpexprs.exp: setting breakpoint at policyd1::function
+FAIL: gdb.cp/cpexprs.exp: setting breakpoint at policyd2::function
+FAIL: gdb.cp/cpexprs.exp: setting breakpoint at policyd3::function
+FAIL: gdb.cp/cpexprs.exp: setting breakpoint at policyd4::function
+FAIL: gdb.cp/cpexprs.exp: setting breakpoint at policyd5::function
+FAIL: gdb.cp/cpexprs.exp: setting breakpoint at policyd<base, operation_1<base> >::function
+FAIL: gdb.cp/cpexprs.exp: setting breakpoint at policyd<char, operation_1<char> >::function
+FAIL: gdb.cp/cpexprs.exp: setting breakpoint at policyd<int, operation_1<int> >::function
+FAIL: gdb.cp/cpexprs.exp: setting breakpoint at policyd<tclass<int>, operation_1<tclass<int> > >::function
...

Not sure that it matters, but in the same test-case, we also have progressions:
...
$ diff -u base/gdb.sum patched/gdb.sum | grep gdb.cp/cpexprs.exp | grep \+PASS
+PASS: gdb.cp/cpexprs.exp: print base::operator fluff const* const*
+PASS: gdb.cp/cpexprs.exp: print base::operator fluff*
+PASS: gdb.cp/cpexprs.exp: print base::operator fluff**
+PASS: gdb.cp/cpexprs.exp: canonicalized conversion operator name 1
+PASS: gdb.cp/cpexprs.exp: canonicalized conversion operator name 2
...
Comment 1 Tom de Vries 2020-04-28 17:37:54 UTC
Easy to reproduce:
...
$ gdb -batch outputs/gdb.cp/cpexprs/cpexprs \
    -ex start \
    -ex "list policy1::function"
Temporary breakpoint 1 at 0x40135f: file cpexprs.cc, line 466.

Temporary breakpoint 1, main (argc=1, argv=0x7fffffffdb98) at cpexprs.cc:466
466       for (i = 0; i < 1000; i++)
Function "policy1::function" not defined.
...
vs without the patch:
...
$ gdb -batch outputs/gdb.cp/cpexprs/cpexprs \
    -ex start \
    -ex "list policy1::function"
Temporary breakpoint 1 at 0x40135f: file cpexprs.cc, line 466.

Temporary breakpoint 1, main (argc=1, argv=0x7fffffffdb98) at cpexprs.cc:466
466       for (i = 0; i < 1000; i++)
65
66      // Some contrived policies
67      template <class T>
68      struct operation_1
69      {
70        static void function (void) { } // operation_1<T>::function
71      };
72
73      template <class T>
74      struct operation_2
...

Same behaviour btw without the -ex start.
Comment 2 Tom de Vries 2020-04-29 04:38:38 UTC
Tentative patch:
...
diff --git a/gdb/linespec.c b/gdb/linespec.c
index 0eb3bc5b8d4..5a975ef4a1a 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -3706,8 +3706,8 @@ find_method (struct linespec_state *self, std::vector<symtab *> *file_symtabs,
 
          superclass_vec.clear ();
          last_result_len = result_names.size ();
-         ++ix;
        }
+      ++ix;
     }
 
   if (!symbols->empty () || !minsyms->empty ())
...
Comment 3 Tom de Vries 2020-04-29 07:59:56 UTC
(In reply to Tom de Vries from comment #2)
> Tentative patch:
> ...
> diff --git a/gdb/linespec.c b/gdb/linespec.c
> index 0eb3bc5b8d4..5a975ef4a1a 100644
> --- a/gdb/linespec.c
> +++ b/gdb/linespec.c
> @@ -3706,8 +3706,8 @@ find_method (struct linespec_state *self,
> std::vector<symtab *> *file_symtabs,
>  
>           superclass_vec.clear ();
>           last_result_len = result_names.size ();
> -         ++ix;
>         }
> +      ++ix;
>      }
>  
>    if (!symbols->empty () || !minsyms->empty ())
> ...

Using this fix, as well as with https://sourceware.org/pipermail/gdb-patches/2020-April/168011.html, we have:
...
# of expected passes            78669
# of unexpected failures        42
# of expected failures          130
# of known failures             73
# of untested testcases         37
# of unsupported tests          83
...
[ See also PR25892. ]
Comment 4 Sourceware Commits 2020-04-29 09:39:40 UTC
The master branch has been updated by Tom de Vries <vries@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ea90f2278cee318976c66bf82284046214fb30af

commit ea90f2278cee318976c66bf82284046214fb30af
Author: Tom de Vries <tdevries@suse.de>
Date:   Wed Apr 29 11:39:36 2020 +0200

    [gdb] Fix range loop index in find_method
    
    With target board debug-types, we have:
    ...
    FAIL: gdb.cp/cpexprs.exp: list policy1::function
    ...
    
    This is a regression triggered by commit 770479f223e "gdb: Fix toplevel types
    with -fdebug-types-section".
    
    However, the FAIL is caused by commit 4dedf84da98 "Change
    decode_compound_collector to use std::vector" which changes a VEC_iterate loop
    into a range loop:
    ...
    -  for (ix = 0; VEC_iterate (symbolp, sym_classes, ix, sym); ++ix)
    +  unsigned int ix = 0;
    +  for (const auto &sym : *sym_classes)
    ...
    but fails to ensure that the increment of ix happens every iteration.
    
    Fix this by calculating the index variable at the start of the loop body:
    ...
      for (const auto &elt : *sym_classes)
        {
          unsigned int ix = &elt - &*sym_classes->begin ();
    ...
    
    Tested on x86_64-linux, with native and target board debug-types.
    
    gdb/ChangeLog:
    
    2020-04-29  Tom de Vries  <tdevries@suse.de>
    
            PR symtab/25889
            * linespec.c (find_method): Fix ix calculation.
    
    gdb/testsuite/ChangeLog:
    
    2020-04-29  Tom de Vries  <tdevries@suse.de>
    
            PR symtab/25889
            * gdb.cp/cpexprs.exp: Adapt for inclusion.
            * gdb.cp/cpexprs-debug-types.exp: New file.  Set -fdebug-types-section
            and include cpexprs.exp.
Comment 5 Tom de Vries 2020-04-29 09:41:40 UTC
Patch with test-case committed, marking resolved-fixed.