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