Make __extern_always_inline usable on clang++ again

Message ID 20140916102016.GM6586@spoyarek.pnq.redhat.com
State Superseded
Headers

Commit Message

Siddhesh Poyarekar Sept. 16, 2014, 10:20 a.m. UTC
  Hi,

The fix for BZ #17266 (884ddc5081278f488ef8cd49951f41cfdbb480ce)
removed changes that had gone into cdefs.h to make
__extern_always_inline usable with clang++.  This patch adds back
support for clang to detect if GNU inlining semantics are available,
this time without breaking the gcc use case.  The check put here is
based on the earlier patch and assertion[1] that checking if
__GNUC_STDC_INLINE__ or __GNUC_GNU_INLINE__ is defined is sufficient
to determine that clang++ suports GNU inlining semantics.

I have kept this test separate from the earlier macro tests on purpose
to keep the conditions simple and readable.

Tested with a simple program that builds with __extern_always_inline
with the patch and fails compilation without it.

#include <stdio.h>
#include <sys/cdefs.h>

extern void foo_alias (void) __asm ("foo");

__extern_always_inline void
foo (void)
{
  puts ("hi oh world!");
  return foo_alias ();
}


void
foo_alias (void)
{
  puts ("hell oh world");
}

int
main ()
{
  foo ();
}

Is this OK for master and 2.20?

Siddhesh

[1] https://sourceware.org/ml/libc-alpha/2012-12/msg00306.html

	[BZ #17266]
	* misc/sys/cdefs.h [!defined __extern_always_inline && defined
	__clang__]: Define __extern_always_inline and __extern_inline
	for clang++.
  

Comments

Jakub Jelinek Sept. 16, 2014, 10:41 a.m. UTC | #1
On Tue, Sep 16, 2014 at 03:50:16PM +0530, Siddhesh Poyarekar wrote:
> [1] https://sourceware.org/ml/libc-alpha/2012-12/msg00306.html
> 
> 	[BZ #17266]
> 	* misc/sys/cdefs.h [!defined __extern_always_inline && defined
> 	__clang__]: Define __extern_always_inline and __extern_inline
> 	for clang++.
> 
> diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
> index d8ee73c..20b2483 100644
> --- a/misc/sys/cdefs.h
> +++ b/misc/sys/cdefs.h
> @@ -330,6 +330,20 @@
>  # endif
>  #endif
>  
> +/* clang++ identifies itself as gcc-4.2, but has support for GNU inlining
> +   semantics, that can be checked fot by using the __GNUC_STDC_INLINE_ and
> +   __GNUC_GNU_INLINE__ macro definitions.  */

s/fot/for/; why are you using a separate hunk for clang instead of using the
earlier one?

> +#if !defined __extern_always_inline && defined __clang__
> +# if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
> +#  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

This doesn't look right.  If you have clang that doesn't have gnu_inline
support, in C++ extern __inline definitely is not the right semantics.
You don't want to define the macros then.

I'd say you want to change:
#if !defined __cplusplus || __GNUC_PREREQ (4,3)
to:
#if !defined __cplusplus || __GNUC_PREREQ (4,3) \
    || (defined __clang__ && (defined __GNUC_STDC_INLINE__ \
			      || defined __GNUC_GNU_INLINE__))

	Jakub
  

Patch

diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
index d8ee73c..20b2483 100644
--- a/misc/sys/cdefs.h
+++ b/misc/sys/cdefs.h
@@ -330,6 +330,20 @@ 
 # endif
 #endif
 
+/* clang++ identifies itself as gcc-4.2, but has support for GNU inlining
+   semantics, that can be checked fot by using the __GNUC_STDC_INLINE_ and
+   __GNUC_GNU_INLINE__ macro definitions.  */
+#if !defined __extern_always_inline && defined __clang__
+# if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
+#  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
+#endif
+
 #ifdef __extern_always_inline
 # define __fortify_function __extern_always_inline __attribute_artificial__
 #endif