[PATCH] [PR79542][Ada] Fix ICE in dwarf2out.c with nested func. inlining

Jason Merrill jason@redhat.com
Mon May 8 16:41:00 GMT 2017


On Wed, May 3, 2017 at 3:22 PM, Jason Merrill <jason@redhat.com> wrote:
> On Tue, Mar 14, 2017 at 8:24 AM, Pierre-Marie de Rodat
> <derodat@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.

Something like this, which also avoids routinely creating DIEs for
local typedefs that will only be pruned away later; this patch doesn't
change the size of .debug_info in cc1plus.
-------------- next part --------------
commit 56cce11181d1296e43cb4d603fc8efc6ac2570fa
Author: Jason Merrill <jason@redhat.com>
Date:   Thu May 4 15:00:51 2017 -0400

    inline-static

diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 6caf598..bf6a65b 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -24355,7 +24355,7 @@ gen_typedef_die (tree decl, dw_die_ref context_die)
   type_die = new_die (DW_TAG_typedef, context_die, decl);
   origin = decl_ultimate_origin (decl);
   if (origin != NULL)
-    add_abstract_origin_attribute (type_die, origin);
+    gcc_unreachable (), add_abstract_origin_attribute (type_die, origin);
   else
     {
       tree type = TREE_TYPE (decl);
@@ -24858,6 +24858,16 @@ process_scope_var (tree stmt, tree decl, tree origin, dw_die_ref context_die)
   else
     die = NULL;
 
+  if ((origin || DECL_ABSTRACT_ORIGIN (decl))
+      && (TREE_CODE (decl_or_origin) == TYPE_DECL
+	  || (VAR_P (decl_or_origin) && TREE_STATIC (decl_or_origin))))
+    {
+      origin = decl_ultimate_origin (decl_or_origin);
+      if (decl && VAR_P (decl))
+	equate_decl_number_to_die (decl, lookup_decl_die (origin));
+      return;
+    }
+
   if (die != NULL && die->die_parent == NULL)
     add_child_die (context_die, die);
   else if (TREE_CODE (decl_or_origin) == IMPORTED_DECL)


More information about the Gcc-patches mailing list