From patchwork Fri Jan 28 16:01:00 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dodji Seketeli X-Patchwork-Id: 80866 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id D8A6DB7118 for ; Sat, 29 Jan 2011 03:01:14 +1100 (EST) Received: (qmail 22367 invoked by alias); 28 Jan 2011 16:01:10 -0000 Received: (qmail 22160 invoked by uid 22791); 28 Jan 2011 16:01:09 -0000 X-SWARE-Spam-Status: No, hits=-5.6 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; Fri, 28 Jan 2011 16:01:04 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id p0SG12kt022515 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 28 Jan 2011 11:01:02 -0500 Received: from adjoa.redhat.com (ovpn-113-97.phx2.redhat.com [10.3.113.97]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p0SG10mW028460; Fri, 28 Jan 2011 11:01:01 -0500 From: Dodji Seketeli To: Jason Merrill Cc: GCC Patches Subject: PR debug/47510 X-URL: http://www.redhat.com Date: Fri, 28 Jan 2011 17:01:00 +0100 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hello, consider the example below: class C { public: C() {} ~C() {} }; typedef struct { C m; } t; typedef t s; s v; The bug is that the DW_TAG_typedef of the naming typedef t has children DIEs that describe the constructor and destructor of the anonymous struct named by t. This is a leftover of PR debug/46101. In this case when callgraph asks the dwarf backend to emit debug info for the constructor of the anonymous struct, get_context_die [called with the anonymous struct's tree] returns the DIE of the naming typedef. The dwarf emitter then hangs the DIE of the constructor off the typedef. This patch strips the naming typedef from the result of get_context_die. Tested on x86_64-unknown-linux-gnu against trunk. diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 2309297..438baec 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -6270,6 +6270,7 @@ static void remove_child_TAG (dw_die_ref, enum dwarf_tag); static void add_child_die (dw_die_ref, dw_die_ref); static dw_die_ref new_die (enum dwarf_tag, dw_die_ref, tree); static dw_die_ref lookup_type_die (tree); +static dw_die_ref strip_naming_typedef (tree, dw_die_ref); static dw_die_ref lookup_type_die_strip_naming_typedef (tree); static void equate_type_number_to_die (tree, dw_die_ref); static hashval_t decl_die_table_hash (const void *); @@ -8044,6 +8045,22 @@ lookup_type_die (tree type) return TYPE_SYMTAB_DIE (type); } +/* Given a TYPE_DIE representing the type TYPE, if TYPE is an + anonymous type named by the typedef TYPE_DIE, return the DIE of the + anonymous type instead the one of the naming typedef. */ + +static inline dw_die_ref +strip_naming_typedef (tree type, dw_die_ref type_die) +{ + if (type + && TREE_CODE (type) == RECORD_TYPE + && type_die + && type_die->die_tag == DW_TAG_typedef + && is_naming_typedef_decl (TYPE_NAME (type))) + type_die = get_AT_ref (type_die, DW_AT_type); + return type_die; +} + /* Like lookup_type_die, but if type is an anonymous type named by a typedef[1], return the DIE of the anonymous type instead the one of the naming typedef. This is because in gen_typedef_die, we did @@ -8058,11 +8075,7 @@ static inline dw_die_ref lookup_type_die_strip_naming_typedef (tree type) { dw_die_ref die = lookup_type_die (type); - if (TREE_CODE (type) == RECORD_TYPE - && die->die_tag == DW_TAG_typedef - && is_naming_typedef_decl (TYPE_NAME (type))) - die = get_AT_ref (die, DW_AT_type); - return die; + return strip_naming_typedef (type, die); } /* Equate a DIE to a given type specifier. */ @@ -20754,7 +20767,10 @@ get_context_die (tree context) { /* Find die that represents this context. */ if (TYPE_P (context)) - return force_type_die (TYPE_MAIN_VARIANT (context)); + { + context = TYPE_MAIN_VARIANT (context); + return strip_naming_typedef (context, force_type_die (context)); + } else return force_decl_die (context); } diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/typedef6.C b/gcc/testsuite/g++.dg/debug/dwarf2/typedef6.C new file mode 100644 index 0000000..8896446 --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/typedef6.C @@ -0,0 +1,30 @@ +// Origin PR debug/ +// { dg-options "-g -dA" } + +class C { +public: + C() {} + ~C() {} +}; +typedef struct { + C m; +} t; +typedef t s; +s v; + +/* + We want to check that we have a DIE describing the typedef t like this: + + .uleb128 0xc # (DIE (0xb8) DW_TAG_typedef) + .ascii "t\0" # DW_AT_name + .byte 0x1 # DW_AT_decl_file (../../prtests/test.cc) + .byte 0xb # DW_AT_decl_line + .long 0x78 # DW_AT_type + + e.g, it should not haven any child DIE -- the bug here was that this + DIE had children DIEs. So we check that the last line is immediately + followed by a line containing the pattern "(DIE (", instead of a + line containing a DW_AT_sibling attribute. + */ + +// { dg-final { scan-assembler-times "\[^\n\r\]*\\(DIE \[^\n\r\]* DW_TAG_typedef\\)\[\n\r\]{1,2}\[^\n\r\].*\"t\\\\0\"\[^\n\r\]*DW_AT_name\[\n\r\]{1,2}\[^\n\r\]*\[\n\r\]{1,2}\[^\n\r\]*\[\n\r\]{1,2}\[^\n\r\]*DW_AT_type\[\n\r\]{1,2}\[^\n\r\]*\\(DIE" 1 } }