> > 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"); > + }