Fix crash in dwarf2read.c with template parameters
authorTom Tromey <tromey@adacore.com>
Mon, 22 Apr 2019 17:46:47 +0000 (11:46 -0600)
committerTom Tromey <tromey@adacore.com>
Tue, 30 Apr 2019 13:25:03 +0000 (07:25 -0600)
PR c++/24470 concerns a crash in dwarf2read.c that occurs with a
particular test case.

The issue turns out to be that process_structure_scope will pass NULL
to symbol_symtab.  This happens because new_symbol decided not to
create a symbol for the particular DIE.

This patch fixes the problem by finding another reasonably-appropriate
symtab to use instead; issuing a complaint if one cannot be found for
some reason.

As mentioned in the bug, I think there are other bugs here.  For
example, when using "ptype" on the "l" object in the test case, I
think I would expect to see the template parameter.  I didn't research
this too closely, since it seemed more important to fix the crash.

Tested on x86-64 Fedora 29.

I'd like to check this in to the 8.3 branch as well.

2019-04-30  Tom Tromey  <tromey@adacore.com>

PR c++/24470:
* dwarf2read.c (process_structure_scope): Handle case where type
has template parameters but no symbol was created.

gdb/testsuite/ChangeLog
2019-04-30  Tom Tromey  <tromey@adacore.com>

PR c++/24470:
* gdb.cp/temargs.cc: Add test code from PR.

gdb/ChangeLog
gdb/dwarf2read.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.cp/temargs.cc

index f4a50e1..1e2f0eb 100644 (file)
@@ -1,3 +1,9 @@
+2019-04-30  Tom Tromey  <tromey@adacore.com>
+
+       PR c++/24470:
+       * dwarf2read.c (process_structure_scope): Handle case where type
+       has template parameters but no symbol was created.
+
 2019-04-30  Andrew Burgess  <andrew.burgess@embecosm.com>
            Chris January  <chris.january@arm.com>
 
index 571fe1e..751c59c 100644 (file)
@@ -16212,13 +16212,34 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
 
       if (has_template_parameters)
        {
-         /* Make sure that the symtab is set on the new symbols.
-            Even though they don't appear in this symtab directly,
-            other parts of gdb assume that symbols do, and this is
-            reasonably true.  */
-         for (int i = 0; i < TYPE_N_TEMPLATE_ARGUMENTS (type); ++i)
-           symbol_set_symtab (TYPE_TEMPLATE_ARGUMENT (type, i),
-                              symbol_symtab (sym));
+         struct symtab *symtab;
+         if (sym != nullptr)
+           symtab = symbol_symtab (sym);
+         else if (cu->line_header != nullptr)
+           {
+             /* Any related symtab will do.  */
+             symtab
+               = cu->line_header->file_name_at (file_name_index (1))->symtab;
+           }
+         else
+           {
+             symtab = nullptr;
+             complaint (_("could not find suitable "
+                          "symtab for template parameter"
+                          " - DIE at %s [in module %s]"),
+                        sect_offset_str (die->sect_off),
+                        objfile_name (objfile));
+           }
+
+         if (symtab != nullptr)
+           {
+             /* Make sure that the symtab is set on the new symbols.
+                Even though they don't appear in this symtab directly,
+                other parts of gdb assume that symbols do, and this is
+                reasonably true.  */
+             for (int i = 0; i < TYPE_N_TEMPLATE_ARGUMENTS (type); ++i)
+               symbol_set_symtab (TYPE_TEMPLATE_ARGUMENT (type, i), symtab);
+           }
        }
     }
 }
index d3be74d..41aae07 100644 (file)
@@ -1,3 +1,8 @@
+2019-04-30  Tom Tromey  <tromey@adacore.com>
+
+       PR c++/24470:
+       * gdb.cp/temargs.cc: Add test code from PR.
+
 2019-04-30  Andrew Burgess  <andrew.burgess@embecosm.com>
 
        * gdb.fortran/vla-datatypes.exp: Update expected results.
index dc06165..d2a85f9 100644 (file)
@@ -80,6 +80,29 @@ struct K3
   }
 };
 
+namespace pr24470
+{
+// From PR c++/24470
+// This caused a gdb crash during startup.
+
+template <int a> struct b {};
+template <typename, typename> struct c {
+  template <long d> using e = b<d>;
+  void k(e<0>);
+};
+template <typename, template <typename, typename> class, unsigned long...>
+struct m;
+template <typename g, template <typename, typename> class h, unsigned long i>
+struct m<g, h, i> {
+  using j = b<i>;
+};
+struct n {
+  template <typename g> using f = typename m<g, c, 0>::j;
+};
+
+n::f<int> l;
+}
+
 int main ()
 {
   Base<double, 23, &a_global, &S::f> base;