This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc 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]

Re: [PATCH] Revert to defining __extern_inline only for g++-4.3+


On Wed, Aug 13, 2014 at 08:51:22PM +0000, Joseph S. Myers wrote:
> On Wed, 13 Aug 2014, Siddhesh Poyarekar wrote:
> > The check for only __GNUC_STDC_INLINE__ and __GNUC_GNU_INLINE__ may
> > not be sufficient since those flags were added during initial support
> > for C99 inlining semantics.  There is also a problem with always
> > defining __extern_inline and __extern_always_inline, since it enables
> > inline wrapper functions even when GNU inlining semantics are not
> > guaranteed.  This, along with the possibility of such wrappers using
> > redirection (btowc for example) could result in compiler generating an
> > infinitely recusrive call to the function.
> 
> Are you describing a problem that was user-visible in a glibc release?  (I 
> guess so, since you don't mention any post-2012 commits as having caused a 
> regression.)  What specifically is the problem (building what, with what 
> compiler versions)?  A bug report in glibc Bugzilla is needed if it was 
> user-visible in a release.

Support for pre-4.3 gcc in C++ has been broken with those 2012 changes.
Consider say:

#include <wchar.h>

volatile int i = ' ';
wint_t (*fn) (int) = btowc;

int
main ()
{
  asm ("");
  i = fn (i);
  return 0;
}

When this is compiled e.g. with g++ 3.2, because of the incorrect
BZ #14530, #13741 fix, the program will recurse endlessly.
That is because g++ < 4.3 only provided the C++ inline semantics, not
gnu_inline, but when glibc headers use __extern_inline,
__extern_always_inline or __fortify_function, they rely on GNU extern inline
semantics.  The C++ inline semantics when btowc can't be inlined is
that the compiler emits a comdat out of line, but btowc is:
extern wint_t __btowc_alias (int __c) __asm ("btowc");

__extern_inline wint_t
__NTH (btowc (int __c))
{ return (__builtin_constant_p (__c) && __c >= '\0' && __c <= '\x7f'
          ? (wint_t) __c : __btowc_alias (__c)); }

When the compiler emits out of line copy of this, it will be e.g. on
i?86/x86_64 .globl btowc; btowc: jmp btowc;
Similarly with any other __extern_*inline functions in glibc headers that
sometimes call the original function through aliases.
One can get the problematic definitions out of line even with
-fkeep-inline-functions and similar.

So, what Siddhesh's patch does is it restores the old state, where
__extern_inline/__extern_always_inline (and newly __fortify_function)
is only defined if the compiler can actually support that semantics.
In C++, that is only for g++ known to support gnu_inline attribute in C++.

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]