[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