This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
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 <ebotcazou@adacore.com> * tree-inline.c (remap_decl): Preserve DECL_ORIGINAL_TYPE invariant. -- Eric Botcazou
Index: tree-inline.c =================================================================== --- tree-inline.c (revision 237677) +++ tree-inline.c (working copy) @@ -367,7 +367,18 @@ remap_decl (tree decl, copy_body_data *i /* 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); + { + DECL_ORIGINAL_TYPE (t) = remap_type (DECL_ORIGINAL_TYPE (t), id); + + /* Preserve the invariant that DECL_ORIGINAL_TYPE != TREE_TYPE. */ + if (DECL_ORIGINAL_TYPE (t) == TREE_TYPE (t)) + { + tree x = build_variant_type_copy (TREE_TYPE (t)); + TYPE_STUB_DECL (x) = TYPE_STUB_DECL (TREE_TYPE (t)); + TYPE_NAME (x) = t; + DECL_ORIGINAL_TYPE (t) = x; + } + } /* Remap sizes as necessary. */ walk_tree (&DECL_SIZE (t), copy_tree_body_r, id, NULL);
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |