This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [rfc] Work around invalid G++ DWARF for unnamed aggregates


Tom Tromey wrote:
> >>>>> "Ulrich" == Ulrich Weigand <uweigand@de.ibm.com> writes:
> 
> Ulrich> It should be easy to work around this problem with older GCC
> Ulrich> versions by simply ignoring DW_AT_name attributes with such
> Ulrich> names in dwarf2_name.  The patch below implements this.  It also
> Ulrich> fixes a logic bug in completer.c exposed by this change, where
> Ulrich> in an unnamed struct *every* method was considered to be a
> Ulrich> constructor (instead of none).
> [...]
> Ulrich> Does this look reasonable?
> 
> FWIW, yes, it looks reasonable to me.

Thanks for having a look!

Due to a conflict with Keith's recent patch, I've had to rework the
dwarf2_name change a bit.  Updated patch below.

Retested on powerpc64-linux.  Committed to mainline.

Bye,
Ulrich


ChangeLog:

	* dwarf2read.c (dwarf2_name): Work around GCC bugzilla debug/41828 by
	ignoring spurious DW_AT_name attributes for unnamed structs or unions.
	* completer.c (add_struct_fields): Fix inverted logic.

testsuite/ChangeLog:

	* gdb.cp/inherit.exp (test_ptype_si): XFAIL test for GCC versions
	that do not provide the tagless_struct type name at all.
	(test_print_anon_union): Do not check value of uninitialized
	union member.  Do not use cp_test_ptype_class, so we can accept
	"long" as well as "long int".


Index: gdb/completer.c
===================================================================
RCS file: /cvs/src/src/gdb/completer.c,v
retrieving revision 1.36
diff -u -r1.36 completer.c
--- gdb/completer.c	1 Jan 2010 07:31:30 -0000	1.36
+++ gdb/completer.c	26 Mar 2010 13:57:55 -0000
@@ -401,7 +401,7 @@
 	      computed_type_name = 1;
 	    }
 	  /* Omit constructors from the completion list.  */
-	  if (type_name && strcmp (type_name, name))
+	  if (!type_name || strcmp (type_name, name))
 	    {
 	      output[*nextp] = xstrdup (name);
 	      ++*nextp;
Index: gdb/dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.374
diff -u -r1.374 dwarf2read.c
--- gdb/dwarf2read.c	25 Mar 2010 22:13:15 -0000	1.374
+++ gdb/dwarf2read.c	26 Mar 2010 13:57:57 -0000
@@ -9187,6 +9187,7 @@
       /* These tags always have simple identifiers already; no need
 	 to canonicalize them.  */
       return DW_STRING (attr);
+
     case DW_TAG_subprogram:
       /* Java constructors will all be named "<init>", so return
 	 the class name when we see this special case.  */
@@ -9214,17 +9215,33 @@
 	    }
 	  while (die->tag != DW_TAG_compile_unit);
 	}
-      /* fall through */
+      break;
+
+    case DW_TAG_class_type:
+    case DW_TAG_interface_type:
+    case DW_TAG_structure_type:
+    case DW_TAG_union_type:
+      /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
+	 structures or unions.  These were of the form "._%d" in GCC 4.1,
+	 or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3
+	 and GCC 4.4.  We work around this problem by ignoring these.  */
+      if (strncmp (DW_STRING (attr), "._", 2) == 0
+	  || strncmp (DW_STRING (attr), "<anonymous", 10) == 0)
+	return NULL;
+      break;
+
     default:
-      if (!DW_STRING_IS_CANONICAL (attr))
-	{
-	  DW_STRING (attr)
-	    = dwarf2_canonicalize_name (DW_STRING (attr), cu,
-					&cu->objfile->objfile_obstack);
-	  DW_STRING_IS_CANONICAL (attr) = 1;
-	}
-      return DW_STRING (attr);
+      break;
+    }
+
+  if (!DW_STRING_IS_CANONICAL (attr))
+    {
+      DW_STRING (attr)
+	= dwarf2_canonicalize_name (DW_STRING (attr), cu,
+				    &cu->objfile->objfile_obstack);
+      DW_STRING_IS_CANONICAL (attr) = 1;
     }
+  return DW_STRING (attr);
 }
 
 /* Return the die that this die in an extension of, or NULL if there
Index: gdb/testsuite/gdb.cp/inherit.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/inherit.exp,v
retrieving revision 1.15
diff -u -r1.15 inherit.exp
--- gdb/testsuite/gdb.cp/inherit.exp	1 Jan 2010 07:32:01 -0000	1.15
+++ gdb/testsuite/gdb.cp/inherit.exp	26 Mar 2010 13:57:57 -0000
@@ -114,6 +114,11 @@
 	    # gcc 3.4.1 -gstabs+
 	    pass "$name"
 	}
+	-re "No symbol \"tagless_struct\" in current context.$nl$gdb_prompt $" {
+	    # Several GCC 4.x versions provide neither a DW_TAG_typedef DIE
+	    # nor use the typedef name as struct tag name.
+	    xfail "$name"
+	}
     }
 
     set name "ptype variable of type tagless struct"
@@ -490,25 +495,20 @@
 
     set name "print variable of type anonymous union"
     gdb_test_multiple "print g_anon_union" $name {
-	-re "$vhn = \{one = 1, \{a = 2, b = 2\}\}$nl$gdb_prompt $" {
+	-re "$vhn = \{one = 1, \{a = 2, b = \[0-9\]+\}\}$nl$gdb_prompt $" {
 	    pass $name
 	}
     }
 
-    # The nested union prints as a multi-line field, but the class body
-    # scanner is inherently line-oriented.  This is ugly but it works.
-
-    cp_test_ptype_class \
-	"ptype g_anon_union" "print type of anonymous union" \
-	"class" "class_with_anon_union" \
-	{
-	    { field public "int one;" }
-	    { field public "union \{" }
-	    { field public "int a;" }
-	    { field public "long int b;" }
-	    { field public "\};" }
+    set name "print type of anonymous union"
+    set re_tag "class_with_anon_union"
+    set re_class "(class $re_tag \{${ws}public:|struct $re_tag\{)"
+    set re_fields "int one;${ws}union \{${ws}int a;${ws}long( int)? b;${ws}\};"
+    gdb_test_multiple "ptype g_anon_union" $name {
+	-re "type = $re_class${ws}$re_fields$nl\}$nl$gdb_prompt $" {
+	    pass $name
 	}
-
+    }
 }
 
 


-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]