[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