This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch] preserve DECL_ORIGINAL_TYPE invariant in remap_decl
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: Eric Botcazou <ebotcazou at adacore dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 24 Jun 2016 06:04:15 -0700
- Subject: Re: [patch] preserve DECL_ORIGINAL_TYPE invariant in remap_decl
- Authentication-results: sourceware.org; auth=none
- References: <2533931 dot OeIyqvVdZO at polaris>
On Wed, Jun 22, 2016 at 2:12 AM, Eric Botcazou <ebotcazou@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 <ebotcazou@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.