From: Tom Tromey <tromey@redhat.com>
To: Jan Kratochvil <jan.kratochvil@redhat.com>
Cc: gdb-patches@sourceware.org
Subject: Re: RFC: handle case arising from GCC PR 47510
Date: Wed, 02 Feb 2011 22:04:00 -0000 [thread overview]
Message-ID: <m34o8mf60k.fsf@fleche.redhat.com> (raw)
In-Reply-To: <20110202211220.GA9781@host1.dyn.jankratochvil.net> (Jan Kratochvil's message of "Wed, 2 Feb 2011 22:12:20 +0100")
Tom> + struct die_info fake = *die;
Jan> fake.attrs are invalid now while being accessed by new_symbol.
Thanks, I forgot about that.
I fixed it by temporarily changing die->tag.
Tom> +++ b/gdb/testsuite/gdb.cp/anon-struct.cc
Jan> No copyright needed?
Fixed.
Tom> +public:
Tom> + C() {}
Tom> + ~C() {}
Jan> If the destructor is not present maybe_smash_one_typedef() will not
Jan> work. And GDB crashes now due to it, that should be
Jan> sanity-protected anyway.
The class C is not the problem in this test case. I think C just exists
to make sure that the "anonymous" struct is not a POD.
maybe_smash_one_typedef won't be called for C, because C has a name.
I don't understand about GDB crashing now due to C.
Jan> I would remove the intermediate type `S', it was there fore more
Jan> illustrative purposes.
Done.
Jan> I do not fully grok this change, it goes half way. Why two
Jan> artificial methods are not non-unique?
My understanding is that this loop is trying to filter out artificial
methods in a case like:
class K {
K(int) { ... }
};
Here, I think, the user can type "ptype K::K" and get "K::K(int)" --
which makes some kind of sense, ignoring the compiler-generated
K::K(void). At least, that is what I think it all means. I am not sure
this code is really correct, but this part of the patch is just avoiding
a crash.
I don't think it is possible for this loop to see two artificial
methods.
Tom
2011-02-02 Tom Tromey <tromey@redhat.com>
* valops.c (value_struct_elt_for_reference): Refine artificial
type logic. Call error if j==-1.
* dwarf2read.c (maybe_smash_one_typedef): New function.
(process_die) <DW_TAG_typedef>: Use maybe_smash_one_typedef.
2011-02-02 Tom Tromey <tromey@redhat.com>
* gdb.cp/anon-struct.cc: New file.
* gdb.cp/anon-struct.exp: New file.
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 6a98d57..61feb60 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -4621,6 +4621,40 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
do_cleanups (back_to);
}
+/* Fix up a typedef to an anonymous structure, for C++.
+ Return 1 if the smashing was done, 0 otherwise.
+
+ In C++, a typedef can give a name to an anonymous structure. See
+ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47510.
+
+ We detect this situation and smash a name into the anonymous
+ struct. */
+
+static int
+maybe_smash_one_typedef (struct type *typedef_type, const char *base_name)
+{
+ struct type *struct_type = TYPE_TARGET_TYPE (typedef_type);
+ int i;
+
+ for (i = 0; i < TYPE_NFN_FIELDS (struct_type); ++i)
+ {
+ if (TYPE_FN_FIELDLIST_NAME (struct_type, i)
+ && TYPE_FN_FIELDLIST_NAME (struct_type, i)[0] == '~'
+ && strcmp (TYPE_FN_FIELDLIST_NAME (struct_type, i) + 1,
+ base_name) == 0)
+ {
+ /* Found a destructor with the same name as our typedef, so
+ proceed with smashing. */
+ TYPE_TAG_NAME (struct_type) = TYPE_NAME (typedef_type);
+ TYPE_NAME (struct_type) = TYPE_NAME (typedef_type);
+
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
/* Process a die and its children. */
static void
@@ -4669,11 +4703,34 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
case DW_TAG_base_type:
case DW_TAG_subrange_type:
- case DW_TAG_typedef:
/* Add a typedef symbol for the type definition, if it has a
DW_AT_name. */
new_symbol (die, read_type_die (die, cu), cu);
break;
+
+ case DW_TAG_typedef:
+ {
+ struct type *this_type = read_type_die (die, cu);
+
+ if (cu->language == language_cplus
+ && TYPE_CODE (TYPE_TARGET_TYPE (this_type)) == TYPE_CODE_STRUCT
+ && TYPE_TAG_NAME (TYPE_TARGET_TYPE (this_type)) == NULL
+ && maybe_smash_one_typedef (this_type, dwarf2_name (die, cu)))
+ {
+ /* Pretend this DIE is a structure, for new_symbol. */
+ die->tag = DW_TAG_structure_type;
+ new_symbol (die, TYPE_TARGET_TYPE (this_type), cu);
+ die->tag = DW_TAG_typedef;
+ }
+ else
+ {
+ /* Add a typedef symbol for the type definition, if it has
+ a DW_AT_name. */
+ new_symbol (die, this_type, cu);
+ }
+ }
+ break;
+
case DW_TAG_common_block:
read_common_block (die, cu);
break;
diff --git a/gdb/testsuite/gdb.cp/anon-struct.cc b/gdb/testsuite/gdb.cp/anon-struct.cc
new file mode 100644
index 0000000..d1085c9
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/anon-struct.cc
@@ -0,0 +1,33 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2011 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+class C {
+public:
+ C() {}
+ ~C() {}
+};
+
+typedef struct {
+ C m;
+} t;
+
+t v;
+
+int main()
+{
+}
diff --git a/gdb/testsuite/gdb.cp/anon-struct.exp b/gdb/testsuite/gdb.cp/anon-struct.exp
new file mode 100644
index 0000000..a250d19
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/anon-struct.exp
@@ -0,0 +1,25 @@
+# Tests for anonymous union support.
+# Copyright 2011 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+set testfile anon-struct
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug c++}] } {
+ return -1
+}
+
+gdb_test "ptype t::t" "type = void \\(t \\* const\\)" \
+ "print type of t::t"
diff --git a/gdb/valops.c b/gdb/valops.c
index 24c2269..0287092 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -3238,25 +3238,32 @@ value_struct_elt_for_reference (struct type *domain, int offset,
int ii;
j = -1;
- for (ii = 0; ii < TYPE_FN_FIELDLIST_LENGTH (t, i);
- ++ii)
+ for (ii = 0; ii < len; ++ii)
{
/* Skip artificial methods. This is necessary if,
for example, the user wants to "print
subclass::subclass" with only one user-defined
- constructor. There is no ambiguity in this
- case. */
+ constructor. There is no ambiguity in this case.
+ We are careful here to allow artificial methods
+ if they are the unique result. */
if (TYPE_FN_FIELD_ARTIFICIAL (f, ii))
- continue;
+ {
+ if (j == -1)
+ j = ii;
+ continue;
+ }
/* Desired method is ambiguous if more than one
method is defined. */
- if (j != -1)
+ if (j != -1 && !TYPE_FN_FIELD_ARTIFICIAL (f, j))
error (_("non-unique member `%s' requires "
"type instantiation"), name);
j = ii;
}
+
+ if (j == -1)
+ error (_("no matching member function"));
}
if (TYPE_FN_FIELD_STATIC_P (f, j))
next prev parent reply other threads:[~2011-02-02 22:04 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-02-02 20:21 Tom Tromey
2011-02-02 21:12 ` Jan Kratochvil
2011-02-02 21:47 ` Michael Snyder
2011-02-02 21:50 ` copyright in testcase .cc [Re: RFC: handle case arising from GCC PR 47510] Jan Kratochvil
2011-02-02 21:58 ` Tom Tromey
2011-02-02 22:04 ` Tom Tromey [this message]
2011-02-03 8:59 ` RFC: handle case arising from GCC PR 47510 Jan Kratochvil
2011-02-03 21:07 ` Tom Tromey
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m34o8mf60k.fsf@fleche.redhat.com \
--to=tromey@redhat.com \
--cc=gdb-patches@sourceware.org \
--cc=jan.kratochvil@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox