This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] Revert to defining __extern_inline only for g++-4.3+
- From: Jakub Jelinek <jakub at redhat dot com>
- To: "Joseph S. Myers" <joseph at codesourcery dot com>
- Cc: Siddhesh Poyarekar <siddhesh at redhat dot com>, libc-alpha at sourceware dot org
- Date: Wed, 13 Aug 2014 23:20:46 +0200
- Subject: Re: [PATCH] Revert to defining __extern_inline only for g++-4.3+
- Authentication-results: sourceware.org; auth=none
- References: <20140813182334 dot GA3507 at spoyarek dot pnq dot redhat dot com> <Pine dot LNX dot 4 dot 64 dot 1408132050030 dot 16622 at digraph dot polyomino dot org dot uk>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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