From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15544 invoked by alias); 2 Feb 2011 22:04:05 -0000 Received: (qmail 15535 invoked by uid 22791); 2 Feb 2011 22:04:04 -0000 X-SWARE-Spam-Status: No, hits=-6.9 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 02 Feb 2011 22:03:59 +0000 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id p12M3vq0000754 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 2 Feb 2011 17:03:58 -0500 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p12M3vCr014505; Wed, 2 Feb 2011 17:03:57 -0500 Received: from opsy.redhat.com (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id p12M3uM7022401; Wed, 2 Feb 2011 17:03:56 -0500 Received: by opsy.redhat.com (Postfix, from userid 500) id 11E343783AD; Wed, 2 Feb 2011 15:03:56 -0700 (MST) From: Tom Tromey To: Jan Kratochvil Cc: gdb-patches@sourceware.org Subject: Re: RFC: handle case arising from GCC PR 47510 References: <20110202211220.GA9781@host1.dyn.jankratochvil.net> Date: Wed, 02 Feb 2011 22:04:00 -0000 In-Reply-To: <20110202211220.GA9781@host1.dyn.jankratochvil.net> (Jan Kratochvil's message of "Wed, 2 Feb 2011 22:12:20 +0100") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-02/txt/msg00036.txt.bz2 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 * 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) : Use maybe_smash_one_typedef. 2011-02-02 Tom Tromey * 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 . + */ + +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 . + +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))