On Wed, Jun 22, 2016 at 2:12 AM, Eric Botcazou <ebotca...@adacore.com> wrote: > Hi, > > the invariant is that DECL_ORIGINAL_TYPE (t) != TREE_TYPE (t) as pointer value > if t is a TYPE_DECL. It's enforced by the DWARF back-end: > > if (DECL_ORIGINAL_TYPE (decl)) > { > type = DECL_ORIGINAL_TYPE (decl); > > if (type == error_mark_node) > return; > > gcc_assert (type != TREE_TYPE (decl)); > > [...] > > /* Prevent broken recursion; we can't hand off to the same type. */ > gcc_assert (DECL_ORIGINAL_TYPE (TYPE_NAME (type)) != type); > > Unfortunately it can be easily broken in remap_decl: > > /* Remap types, if necessary. */ > TREE_TYPE (t) = remap_type (TREE_TYPE (t), id); > if (TREE_CODE (t) == TYPE_DECL) > DECL_ORIGINAL_TYPE (t) = remap_type (DECL_ORIGINAL_TYPE (t), id); > > If TREE_TYPE (t) is for example a pointer to a variably-modified type, then > the types are remapped by means of build_pointer_type_for_mode, which means > that they are also canonicalized, so TREE_TYPE (t) == DECL_ORIGINAL_TYPE (t) > after the remapping. This happens in Ada, but also in C for: > > extern void bar (void *) __attribute__((noreturn)); > > static int foo (int i, unsigned int n) > { > if (i == 0) > { > struct S { int a[n]; }; > typedef struct S *ptr; > ptr p = __builtin_malloc (sizeof (struct S)); > bar (p); > } > > return i > 0 ? 1 : -1; > } > > int f1 (int i, unsigned int n) > { > return foo (i, n); > } > > int f2 (int i, unsigned int n) > { > return foo (i, n); > } > > when foo is split into 2 parts at -O2. > > This generally goes unnoticed because the inliner sets DECL_ABSTRACT_ORIGIN on > the remapped TYPE_DECL, so gen_typedef_die skips it: > > 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); > else > { > tree type; > > add_name_and_src_coords_attributes (type_die, decl); > if (DECL_ORIGINAL_TYPE (decl)) > { > type = DECL_ORIGINAL_TYPE (decl); > > if (type == error_mark_node) > return; > > gcc_assert (type != TREE_TYPE (decl)); > equate_type_number_to_die (TREE_TYPE (decl), type_die); > } > > But, in LTO mode, DECL_ABSTRACT_ORIGIN is not streamed so it's another story > and this for example breaks the LTO build of the Ada compiler at -O2 -g. > > Hence the attached ad-hoc attempt at preserving the invariant in remap_decl, > which appears to work and is sufficient to fix the aforementioned bootstrap. > > Tested on x86_64-suse-linux, OK for the mainline? > > > 2016-06-22 Eric Botcazou <ebotca...@adacore.com> > > * tree-inline.c (remap_decl): Preserve DECL_ORIGINAL_TYPE invariant. >
This caused: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71645 -- H.J.