> 
> Currently a _lot_ of packages fail to build with LTO because LTO
> messes up fortify wrappers by replacing the call to the alias with
> the symbol itself, making the wrapper look like infinitely
> recursing.
> 
> The following patch fixes this by dropping the bodies of
> DECL_EXTERN always-inline functions on the floor before IPA
> (and when doing LTO).  IMHO we should at some point do this
> unconditional on LTO as the early inliner is supposed to
> remove all references to always-inline functions.
> 
> I'm not 100% sure about the cgraph API use to drop the function
> body, but at least it seems to work ;)  I'm not sure if we want
> to restrict the set of functions to apply this even more than
> just those with always-inline and DECL_EXTERNAL set?
> 
> Now double-checking with a fortified LTO bootstrap.
> 
> Ok for trunk?
> 
> Thanks,
> Richard.
> 
> 2014-03-24  Richard Biener  <rguent...@suse.de>
> 
>       PR lto/59626
>       * passes.c (ipa_write_summaries): Drop function bodies of
>       extern always-inline functions.

I think it is probably better to drop these during unreachable function removal
same way as we drop extern inlines after inlining (just use cgraph_state check 
to
see if we are past early inlining). I will make patch this afternoon.

Why do you need to remove the always_inline attribute? And how do I do fortified
LTO bootstrap? :)

Honza
> 
>       * gcc.dg/lto/pr59626_0.c: New testcase.
>       * gcc.dg/lto/pr59626_1.c: Likewise.
> 
> Index: gcc/passes.c
> ===================================================================
> *** gcc/passes.c      (revision 208745)
> --- gcc/passes.c      (working copy)
> *************** ipa_write_summaries (void)
> *** 2390,2404 ****
>   
>         if (cgraph_function_with_gimple_body_p (node))
>       {
> !       /* When streaming out references to statements as part of some IPA
> !          pass summary, the statements need to have uids assigned and the
> !          following does that for all the IPA passes here. Naturally, this
> !          ordering then matches the one IPA-passes get in their stmt_fixup
> !          hooks.  */
> ! 
> !       push_cfun (DECL_STRUCT_FUNCTION (node->decl));
> !       renumber_gimple_stmt_uids ();
> !       pop_cfun ();
>       }
>         if (node->definition)
>           lto_set_symtab_encoder_in_partition (encoder, node);
> --- 2396,2427 ----
>   
>         if (cgraph_function_with_gimple_body_p (node))
>       {
> !       if (DECL_EXTERNAL (node->decl)
> !           && lookup_attribute ("always_inline",
> !                                DECL_ATTRIBUTES (node->decl)) != NULL)
> !         {
> !           /* We mess up uses of extern always-inline wrappers that
> !              end up calling an alias to itself like glibc _FORTIFY_SOURCE
> !              wrappers.  Simply drop the bodies of the extern inlines
> !              here to avoid that.  */
> !           cgraph_release_function_body (node);
> !           node->analyzed = false;
> !           node->definition = false;
> !           DECL_ATTRIBUTES (node->decl)
> !             = remove_attribute ("always_inline",
> !                                 DECL_ATTRIBUTES (node->decl));
> !         }
> !       else
> !         {
> !           /* When streaming out references to statements as part of some
> !              IPA pass summary, the statements need to have uids assigned
> !              and the following does that for all the IPA passes here.
> !              Naturally, this ordering then matches the one IPA-passes get
> !              in their stmt_fixup hooks.  */
> !           push_cfun (DECL_STRUCT_FUNCTION (node->decl));
> !           renumber_gimple_stmt_uids ();
> !           pop_cfun ();
> !         }
>       }
>         if (node->definition)
>           lto_set_symtab_encoder_in_partition (encoder, node);
> Index: gcc/testsuite/gcc.dg/lto/pr59626_0.c
> ===================================================================
> *** gcc/testsuite/gcc.dg/lto/pr59626_0.c      (revision 0)
> --- gcc/testsuite/gcc.dg/lto/pr59626_0.c      (working copy)
> ***************
> *** 0 ****
> --- 1,15 ----
> + /* { dg-lto-do run } */
> + 
> + int __atoi  (const char *) __asm__("atoi");
> + extern inline __attribute__((always_inline,gnu_inline))
> + int atoi (const char *x)
> + {
> +   return __atoi (x);
> + }
> + 
> + int bar (int (*)(const char *));
> + 
> + int main()
> + {
> +   return bar (atoi);
> + }
> Index: gcc/testsuite/gcc.dg/lto/pr59626_1.c
> ===================================================================
> *** gcc/testsuite/gcc.dg/lto/pr59626_1.c      (revision 0)
> --- gcc/testsuite/gcc.dg/lto/pr59626_1.c      (working copy)
> ***************
> *** 0 ****
> --- 1,4 ----
> + int bar (int (*fn)(const char *))
> + {
> +   return fn ("0");
> + }

Reply via email to