OK.
On Thu, Jan 5, 2017 at 8:19 AM, Richard Biener <rguent...@suse.de> wrote: > > The following fixes a LTO dwarf2out ICE when mixing C and C++ TUs. > is_cxx then claims we're C++ but we are not happy to see a C typedef > handled by > > gen_typedef_die (tree decl, dw_die_ref context_die) > { > ... > if (is_naming_typedef_decl (TYPE_NAME (type))) > { > /* Here, we are in the case of decl being a typedef naming > an anonymous type, e.g: > typedef struct {...} foo; > In that case TREE_TYPE (decl) is not a typedef variant > type and TYPE_NAME of the anonymous type is set to the > TYPE_DECL of the typedef. This construct is emitted by > the C++ FE. > > TYPE is the anonymous struct named by the typedef > DECL. As we need the DW_AT_type attribute of the > DW_TAG_typedef to point to the DIE of TYPE, let's > generate that DIE right away. add_type_attribute > called below will then pick (via lookup_type_die) that > anonymous struct DIE. */ > if (!TREE_ASM_WRITTEN (type)) > gen_tagged_type_die (type, context_die, > DINFO_USAGE_DIR_USE); > > /* This is a GNU Extension. We are adding a > DW_AT_linkage_name attribute to the DIE of the > anonymous struct TYPE. The value of that attribute > is the name of the typedef decl naming the anonymous > struct. This greatly eases the work of consumers of > this debug info. */ > add_linkage_name_raw (lookup_type_die (type), decl); > } > > Here gen_tagged_type_die -> gen_member_die eventually ICEs not expecting a > variant type. "Fixing" that assert just shows that add_linkage_name_raw > fails as we do not have a DECL_ASSEMBLER_NAME for the type decl and > we do not allow deferred asm names late (the C type decl won't ever > get an assembler name anyway...). > > Thus the following provides an overload to is_cxx () we can feed > with context (to see whether the typedef decl was created by the C++ FE). > > Hopefully with GCC 8 we'll get early LTO debug and all these issues > gone... > > LTO bootstrapped and tested on x86_64-unknown-linux-gnu, ok for trunk > and branches? > > Thanks, > Richard. > > 2017-01-05 Richard Biener <rguent...@suse.de> > > PR debug/79000 > * dwarf2out.c (is_cxx): New overload with context. > (is_naming_typedef_decl): Use it. > > * g++.dg/lto/pr79000_0.C: New testcase. > * g++.dg/lto/pr79000_1.c: Likewise. > > Index: gcc/dwarf2out.c > =================================================================== > *** gcc/dwarf2out.c (revision 244093) > --- gcc/dwarf2out.c (working copy) > *************** static int get_AT_flag (dw_die_ref, enum > *** 3356,3361 **** > --- 3356,3362 ---- > static unsigned get_AT_unsigned (dw_die_ref, enum dwarf_attribute); > static inline dw_die_ref get_AT_ref (dw_die_ref, enum dwarf_attribute); > static bool is_cxx (void); > + static bool is_cxx (const_tree); > static bool is_fortran (void); > static bool is_ada (void); > static bool remove_AT (dw_die_ref, enum dwarf_attribute); > *************** is_cxx (void) > *** 4990,4995 **** > --- 4991,5012 ---- > || lang == DW_LANG_C_plus_plus_11 || lang == > DW_LANG_C_plus_plus_14); > } > > + /* Return TRUE if DECL was created by the C++ frontend. */ > + > + static bool > + is_cxx (const_tree decl) > + { > + if (in_lto_p) > + { > + while (DECL_CONTEXT (decl)) > + decl = DECL_CONTEXT (decl); > + if (TREE_CODE (decl) == TRANSLATION_UNIT_DECL > + && TRANSLATION_UNIT_LANGUAGE (decl)) > + return strncmp (TRANSLATION_UNIT_LANGUAGE (decl), "GNU C++", 7) == 0; > + } > + return is_cxx (); > + } > + > /* Return TRUE if the language is Java. */ > > static inline bool > *************** is_naming_typedef_decl (const_tree decl) > *** 24762,24768 **** > /* It looks like Ada produces TYPE_DECLs that are very similar > to C++ naming typedefs but that have different > semantics. Let's be specific to c++ for now. */ > ! || !is_cxx ()) > return FALSE; > > return (DECL_ORIGINAL_TYPE (decl) == NULL_TREE > --- 24779,24785 ---- > /* It looks like Ada produces TYPE_DECLs that are very similar > to C++ naming typedefs but that have different > semantics. Let's be specific to c++ for now. */ > ! || !is_cxx (decl)) > return FALSE; > > return (DECL_ORIGINAL_TYPE (decl) == NULL_TREE > Index: gcc/testsuite/g++.dg/lto/pr79000_0.C > =================================================================== > *** gcc/testsuite/g++.dg/lto/pr79000_0.C (revision 0) > --- gcc/testsuite/g++.dg/lto/pr79000_0.C (working copy) > *************** > *** 0 **** > --- 1,7 ---- > + // { dg-lto-do link } > + // { dg-lto-options { "-flto -g" } } > + // { dg-extra-ld-options "-r -nostdlib" } > + > + struct a { > + a(); > + } b; > Index: gcc/testsuite/g++.dg/lto/pr79000_1.c > =================================================================== > *** gcc/testsuite/g++.dg/lto/pr79000_1.c (revision 0) > --- gcc/testsuite/g++.dg/lto/pr79000_1.c (working copy) > *************** > *** 0 **** > --- 1,5 ---- > + typedef struct a b; > + typedef struct a { } b; > + struct { > + b c; > + } d;