[RFA,8.3] Fix crash in dwarf2read.c with template parameters

Message ID 20190422175920.9574-1-tromey@adacore.com
State New, archived
Headers

Commit Message

Tom Tromey April 22, 2019, 5:59 p.m. UTC
  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.

gdb/ChangeLog
2019-04-22  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-22  Tom Tromey  <tromey@adacore.com>

	PR c++/24470:
	* gdb.cp/temargs.cc: Add test code from PR.
---
 gdb/ChangeLog                   |  6 ++++++
 gdb/dwarf2read.c                | 35 ++++++++++++++++++++++++++-------
 gdb/testsuite/ChangeLog         |  5 +++++
 gdb/testsuite/gdb.cp/temargs.cc | 23 ++++++++++++++++++++++
 4 files changed, 62 insertions(+), 7 deletions(-)
  

Comments

Tom Tromey April 30, 2019, 1:16 p.m. UTC | #1
>>>>> "Tom" == Tom Tromey <tromey@adacore.com> writes:

Tom> PR c++/24470 concerns a crash in dwarf2read.c that occurs with a
Tom> particular test case.

[...]
Tom> I'd like to check this in to the 8.3 branch as well.

I'm going to check this in now.

Tom
  

Patch

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 2d6cb353fbb..4251ed03b46 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -16218,13 +16218,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);
+	    }
 	}
     }
 }
diff --git a/gdb/testsuite/gdb.cp/temargs.cc b/gdb/testsuite/gdb.cp/temargs.cc
index dc061658d49..d2a85f95340 100644
--- a/gdb/testsuite/gdb.cp/temargs.cc
+++ b/gdb/testsuite/gdb.cp/temargs.cc
@@ -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;