[PATCH][dwarf2out] Fix PR79000
Jason Merrill
jason@redhat.com
Thu Jan 5 22:13:00 GMT 2017
OK.
On Thu, Jan 5, 2017 at 8:19 AM, Richard Biener <rguenther@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 <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.
>
> 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;
More information about the Gcc-patches
mailing list