Bug 79000 - ICE: in gen_member_die, at dwarf2out.c:23995
Summary: ICE: in gen_member_die, at dwarf2out.c:23995
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: debug (show other bugs)
Version: 7.0
: P3 normal
Target Milestone: ---
Assignee: Richard Biener
URL:
Keywords: lto
Depends on:
Blocks:
 
Reported: 2017-01-05 07:20 UTC by Markus Trippelsdorf
Modified: 2018-11-20 08:48 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work: 7.0
Known to fail: 6.3.0
Last reconfirmed: 2017-01-05 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Markus Trippelsdorf 2017-01-05 07:20:54 UTC
A Gentoo users emailed me the following mixed C/C++ LTO testcase:

markus@x4 /tmp % cat 1.ii
struct a {
  a();
} b;

markus@x4 /tmp % cat 2.i
typedef struct a b;
typedef struct a {
} b;
struct {
  b c;
} d;

markus@x4 /tmp % gcc -g -flto -r -nostdlib 1.ii 2.i
lto1: internal compiler error: in gen_member_die, at dwarf2out.c:23995
0x6fa800 gen_member_die
        /home/markus/gcc/gcc/dwarf2out.c:23995
0x6fa800 gen_struct_or_union_type_die
        /home/markus/gcc/gcc/dwarf2out.c:24096
0x6fa800 gen_tagged_type_die
        /home/markus/gcc/gcc/dwarf2out.c:24306
0x712040 gen_typedef_die
        /home/markus/gcc/gcc/dwarf2out.c:24213
0x6f787a gen_decl_die
        /home/markus/gcc/gcc/dwarf2out.c:25155
0x6f84ae dwarf2out_decl
        /home/markus/gcc/gcc/dwarf2out.c:25636
0x6f887c dwarf2out_type_decl
        /home/markus/gcc/gcc/dwarf2out.c:25344
0x5eaf33 lto_read_decls
        /home/markus/gcc/gcc/lto/lto.c:1756
0x5ed8e3 lto_file_finalize
        /home/markus/gcc/gcc/lto/lto.c:2038
0x5ed8e3 lto_create_files_from_ids
        /home/markus/gcc/gcc/lto/lto.c:2048
0x5ed8e3 lto_file_read
        /home/markus/gcc/gcc/lto/lto.c:2089
0x5ed8e3 read_cgraph_and_symbols
        /home/markus/gcc/gcc/lto/lto.c:2799
0x5ed8e3 lto_main()
        /home/markus/gcc/gcc/lto/lto.c:3304

Breakpoint 1, gen_member_die (context_die=<optimized out>, type=0x0) at /home/markus/gcc/gcc/dwarf2out.c:23995
23995     gcc_assert (TYPE_MAIN_VARIANT (type) == type);
(gdb) p type
$1 = (tree) 0x0

All supported gcc versions are affected.
Comment 1 Richard Biener 2017-01-05 10:09:17 UTC
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).
Comment 2 Richard Biener 2017-01-09 08:23:30 UTC
Author: rguenth
Date: Mon Jan  9 08:22:58 2017
New Revision: 244217

URL: https://gcc.gnu.org/viewcvs?rev=244217&root=gcc&view=rev
Log:
2017-01-09  Richard Biener  <rguenther@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.

Added:
    trunk/gcc/testsuite/g++.dg/lto/pr79000_0.C
    trunk/gcc/testsuite/g++.dg/lto/pr79000_1.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/dwarf2out.c
    trunk/gcc/testsuite/ChangeLog
Comment 3 Richard Biener 2017-01-09 08:26:21 UTC
Fixed on trunk.  Will eventually backport to GCC 6.
Comment 4 Martin Liška 2018-11-19 14:41:10 UTC
Richi: Can the bug be marked as resolved?
Comment 5 Richard Biener 2018-11-20 08:48:02 UTC
Fixed.