Skip to content

Commit

Permalink
Revert to defining __extern_inline only for gcc-4.3+ (BZ #17266)
Browse files Browse the repository at this point in the history
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.

In fact it was such a recursion that led to this code being written
the way it was; see:

https://bugzilla.redhat.com/show_bug.cgi?id=186410

The initial change was to fix bugs 14530 and 13741, but they can be
resolved by checking if __fortify_function and/or
__extern_always_inline are defined, as it has been done in this patch.
In addition, I have audited uses of __extern_always_inline to make
sure that none of the uses result in compilation errors.

There is however a regression in this patch for llvm, since it reverts
the llvm expectation that __GNUC_STDC_INLINE__ or __GNUC_GNU_INLINE__
definition imply proper extern inline semantics.

2014-09-16  Siddhesh Poyarekar  <siddhesh@redhat.com>
	    Jakub Jelinek  <jakub@redhat.com>

	[BZ #17266]
	* libio/stdio.h: Check definition of __fortify_function
	instead of __extern_always_inline to include bits/stdio2.h.
	* math/bits/math-finite.h [__USE_XOPEN || __USE_ISOC99]: Also
	check if __extern_always_inline is defined.
	[__USE_MISC || __USE_XOPEN]: Likewise.
	[__USE_ISOC99] Likewise.
	* misc/sys/cdefs.h (__fortify_function): Define only if
	__extern_always_inline is defined.
	[!__cplusplus || __GNUC_PREREQ (4,3)]: Revert to defining
	__extern_always_inline and __extern_inline only for g++-4.3
	and newer or a compatible gcc.
  • Loading branch information
Siddhesh Poyarekar committed Sep 16, 2014
1 parent a7b8726 commit 884ddc5
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 14 deletions.
16 changes: 16 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
2014-09-16 Siddhesh Poyarekar <siddhesh@redhat.com>
Jakub Jelinek <jakub@redhat.com>

[BZ #17266]
* libio/stdio.h: Check definition of __fortify_function
instead of __extern_always_inline to include bits/stdio2.h.
* math/bits/math-finite.h [__USE_XOPEN || __USE_ISOC99]: Also
check if __extern_always_inline is defined.
[__USE_MISC || __USE_XOPEN]: Likewise.
[__USE_ISOC99] Likewise.
* misc/sys/cdefs.h (__fortify_function): Define only if
__extern_always_inline is defined.
[!__cplusplus || __GNUC_PREREQ (4,3)]: Revert to defining
__extern_always_inline and __extern_inline only for g++-4.3
and newer or a compatible gcc.

2014-09-15 Andreas Schwab <schwab@linux-m68k.org>

[BZ #17371]
Expand Down
2 changes: 1 addition & 1 deletion libio/stdio.h
Original file line number Diff line number Diff line change
Expand Up @@ -932,7 +932,7 @@ extern void funlockfile (FILE *__stream) __THROW;
#ifdef __USE_EXTERN_INLINES
# include <bits/stdio.h>
#endif
#if __USE_FORTIFY_LEVEL > 0 && defined __extern_always_inline
#if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function
# include <bits/stdio2.h>
#endif
#ifdef __LDBL_COMPAT
Expand Down
8 changes: 5 additions & 3 deletions math/bits/math-finite.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,8 @@ extern long double __REDIRECT_NTH (lgammal_r, (long double, int *),
# endif
#endif

#if defined __USE_XOPEN || defined __USE_ISOC99
#if ((defined __USE_XOPEN || defined __USE_ISOC99) \
&& defined __extern_always_inline)
/* lgamma. */
__extern_always_inline double __NTH (lgamma (double __d))
{
Expand Down Expand Up @@ -284,7 +285,8 @@ __extern_always_inline long double __NTH (lgammal (long double __d))
# endif
#endif

#if defined __USE_MISC || defined __USE_XOPEN
#if ((defined __USE_MISC || defined __USE_XOPEN) \
&& defined __extern_always_inline)
/* gamma. */
__extern_always_inline double __NTH (gamma (double __d))
{
Expand Down Expand Up @@ -422,7 +424,7 @@ extern long double __REDIRECT_NTH (sqrtl, (long double), __sqrtl_finite);
# endif
#endif

#ifdef __USE_ISOC99
#if defined __USE_ISOC99 && defined __extern_always_inline
/* tgamma. */
extern double __gamma_r_finite (double, int *);
__extern_always_inline double __NTH (tgamma (double __d))
Expand Down
21 changes: 11 additions & 10 deletions misc/sys/cdefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@
/* Fortify support. */
#define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1)
#define __bos0(ptr) __builtin_object_size (ptr, 0)
#define __fortify_function __extern_always_inline __attribute_artificial__

#if __GNUC_PREREQ (4,3)
# define __warndecl(name, msg) \
Expand Down Expand Up @@ -318,22 +317,24 @@
# define __attribute_artificial__ /* Ignore */
#endif

#ifdef __GNUC__
/* One of these will be defined if the __gnu_inline__ attribute is
available. In C++, __GNUC_GNU_INLINE__ will be defined even though
__inline does not use the GNU inlining rules. If neither macro is
defined, this version of GCC only supports GNU inline semantics. */
# if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
/* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
inline semantics, unless -fgnu89-inline is used. Using __GNUC_STDC_INLINE__
or __GNUC_GNU_INLINE is not a good enough check for gcc because gcc versions
older than 4.3 may define these macros and still not guarantee GNU inlining
semantics. */
#if !defined __cplusplus || __GNUC_PREREQ (4,3)
# if defined __GNUC_STDC_INLINE__ || defined __cplusplus
# define __extern_inline extern __inline __attribute__ ((__gnu_inline__))
# define __extern_always_inline \
extern __always_inline __attribute__ ((__gnu_inline__))
# else
# define __extern_inline extern __inline
# define __extern_always_inline extern __always_inline
# endif
#else /* Not GCC. */
# define __extern_inline /* Ignore */
# define __extern_always_inline /* Ignore */
#endif

#ifdef __extern_always_inline
# define __fortify_function __extern_always_inline __attribute_artificial__
#endif

/* GCC 4.3 and above allow passing all anonymous arguments of an
Expand Down

0 comments on commit 884ddc5

Please sign in to comment.