https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79000
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |ASSIGNED Last reconfirmed| |2017-01-05 Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org Ever confirmed|0 |1 Known to fail| |7.0 --- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> --- Confirmed. (gdb) p type->type_common.main_variant $3 = <record_type 0x2aaaac231dc8 a> (gdb) p type $4 = <record_type 0x2aaaac231f18 b> we're coming from calling #8 0x00000000007a6f36 in lto_read_decls (decl_data=0x2aaaaaad8000, data=0x2aaaaaaf1628, resolutions=...) at /space/rguenther/src/svn/gcc-7-branch/gcc/lto/lto.c:1756 1756 debug_hooks->type_decl (t, !DECL_FILE_SCOPE_P (t)); on the C11 TU type decl. The type decls type is not the main variant (the C FE builds a type for B with main variant A). But the assert in dwarf2out is weird. We're coming via 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); but the type is from the C FE. Of course we have static bool is_naming_typedef_decl (const_tree decl) { if (decl == NULL_TREE || TREE_CODE (decl) != TYPE_DECL || DECL_NAMELESS (decl) || !is_tagged_type (TREE_TYPE (decl)) || DECL_IS_BUILTIN (decl) || is_redundant_typedef (decl) /* 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 ()) but is_cxx doesn't work (it can't possibly without a context). In LTO we choose a "common" language and set it to C++ when combining C and C++ source. With early LTO debug this will be solved by not generating type DIEs late. Without this I don't see anything better than simply silencing the assert but doing that results in lto1: internal compiler error: in dwarf2out_finish, at dwarf2out.c:29324 0x91b749 dwarf2out_finish /space/rguenther/src/svn/gcc-7-branch/gcc/dwarf2out.c:29324 Please submit a full bug report, (gdb) p *deferred_asm_name $2 = { die = <dw_die_ref 0x2aaaac23c140 DW_TAG_structure_type <parent=0x2aaaac23c000 DW_TAG_compile_unit>>, created_for = <type_decl 0x2aaaac234260 b>, next = 0x0} (gdb) p debug_dwarf_die (0x2aaaac23c140) DIE 0: DW_TAG_structure_type (0x2aaaac23c140) abbrev id: 0 offset: 0 mark: 0 DW_AT_name: "b" DW_AT_byte_size: 0 DW_AT_decl_file: "2.i" (0) DW_AT_decl_line: 2 from the very same code: /* 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); but of course the C type doesn't have a DECL_ASSEMBLER_NAME set... Fixing it with the following works though: Index: gcc/dwarf2out.c =================================================================== --- gcc/dwarf2out.c (revision 244093) +++ gcc/dwarf2out.c (working copy) @@ -3356,6 +3356,7 @@ static int get_AT_flag (dw_die_ref, enum 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); @@ -4990,6 +4991,19 @@ is_cxx (void) || 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) +{ + 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 @@ -24762,7 +24776,7 @@ is_naming_typedef_decl (const_tree decl) /* 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 ()) + || !is_cxx (decl)) return FALSE; return (DECL_ORIGINAL_TYPE (decl) == NULL_TREE (more Java remanents btw...) Mine, either via the above or via early LTO debug (for GCC 8).