http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59626
--- Comment #18 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Jakub Jelinek from comment #5) > But the function doesn't inline itself, that is why it uses the asm alias > and GCC shouldn't be looking through that and merging the two decls because > of that. > > Breaking this breaks pretty much all of glibc -D_FORTIFY_SOURCE, and there > really isn't any other way how to write it. > > To show the reason for the inline: > __fortify_function __nonnull ((1, 2)) __wur ssize_t > __NTH (readlink (const char *__restrict __path, char *__restrict __buf, > size_t __len)) > { > if (__bos (__buf) != (size_t) -1) > { > if (!__builtin_constant_p (__len)) > return __readlink_chk (__path, __buf, __len, __bos (__buf)); > > if ( __len > __bos (__buf)) > return __readlink_chk_warn (__path, __buf, __len, __bos (__buf)); > } > return __readlink_alias (__path, __buf, __len); > } > > The inline must be always_inline, because it is a security matter if it is > inlined or not, and we want it to expand as a call to __readlink_chk if > it needs runtime verification, otherwise as a call to the original function, > not inlined. So, this is really a LTO/IPA bug. Note that __readlink_alias was _not_ declared always-inline and thus at least the call edge (even if eventually re-directing to readlink itself) should not be considered always-inline. But we always check the always-inline flag on the callee decl, even if it was substituted from an alias. As we throw away the callgraph edges it's also hard to maintain this edge property there.