This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [rfc] Work around invalid G++ DWARF for unnamed aggregates
- From: "Ulrich Weigand" <uweigand at de dot ibm dot com>
- To: tromey at redhat dot com
- Cc: gdb-patches at sourceware dot org
- Date: Fri, 26 Mar 2010 19:07:44 +0100 (CET)
- Subject: 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