On Tue, Mar 14, 2017 at 8:24 AM, Pierre-Marie de Rodat
<dero...@adacore.com> wrote:
> Hello,
>
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79542 reports an ICE in
> dwarf2out.c for an Ada testcase built with optimization.
>
> This crash happens during the late generation pass because
> add_gnat_descriptive_type cannot find the type DIE corresponding to some
> descriptive type after having tried to generate it. This is because the
> DIE was generated during the early generation pass, but then pruned by
> the type pruning machinery. So why was it pruned?
>
> We are in a situation where we have cloned types (because of inlining,
> IIUC) whose TYPE_NAME have non-null DECL_ABSTRACT_ORIGIN attributes. As
> a consequence:
>
>   * In modified_type_die, the "handle C typedef types" part calls
>     gen_type_die on the cloned type.
>
>   * gen_type_die matches a typedef variant, and then calls gen_decl_die
>     on its TYPE_NAME, which will end up calling gen_typedef_die.
>
>   * gen_typedef_die checks decl_ultimate_origin for this TYPE_DECL, and
>     finds one, so it only adds a DW_AT_abstract_origin attribute to the
>     DW_TAG_typedef DIE, but the cloned type itself does not get its own
>     DIE.

That seems like a bug; if gen_typedef_die is going to generate a DIE
for a cloned typedef, it needs to associate the type with the DIE.

>   * Back in modified_type_die, the call to lookup_type_die on the type
>     passed to gen_type_die returns NULL.

> In the end, whole type trees, i.e. the ones referenced by
> DECL_ABSTRACT_ORIGIN attributes, are never referenced from type pruning
> "roots" and are thus pruned. The descriptive type at stake here is one
> of them, hence the assertion failure.
>
> This patch attemps to fix that with what seems to be the most sensible
> thing to do in my opinion: updating the "handle C typedef types" part in
> modified_type_die to check decl_ultimate_origin before calling
> gen_type_die: if that function returns something not null, then we know
> that gen_type_die/gen_typedef_die will not generate a DIE for the input
> type, so we try to process the ultimate origin instead.

This soundsn good; the DWARF standard says that we don't need to have
a die at all for the cloned typedef.

> @@ -12496,6 +12496,18 @@ modified_type_die (tree type, int cv_quals, bool 
> reverse,
>
>        if (qualified_type == dtype)
>         {
> +         tree origin
> +          = TYPE_NAME (qualified_type) == NULL
> +            ? NULL
> +            : decl_ultimate_origin (TYPE_NAME (qualified_type));

This is unnecessarily complicated; at this point we already know that
TYPE_NAME (qualified_type) is non-null and in the variable "name".

> +         /* Typedef variants that have an abstract origin don't get their own
> +            type DIE (see gen_typedef_die), so fall back on the ultimate

gen_typedef_die does create a DIE for them, it just doesn't do it
properly.  But we could change gen_typedef_die to abort in that case,
making this comment correct.

Jason

Reply via email to