[PATCH v3 09/19] string: Check if attribute can declared after function declaration

Adhemerval Zanella adhemerval.zanella@linaro.org
Fri Oct 31 20:00:42 GMT 2025


Some symbols that might be auto-generated by the compiler are redefined
to internal alias (for instance mempcpy to __mempcpy).  However, if fortify
is enabled, the fortify wrapper is define before the alias re-defined and
clang warns attribute declaration must precede definition.

Use an asm alias if compiler does not support it, instead of an
attribute.
---
 config.h.in      |  3 +++
 configure        | 29 +++++++++++++++++++++++++++++
 configure.ac     | 20 ++++++++++++++++++++
 include/string.h |  5 +++++
 4 files changed, 57 insertions(+)

diff --git a/config.h.in b/config.h.in
index 53788830606..8a997f0d4b4 100644
--- a/config.h.in
+++ b/config.h.in
@@ -317,4 +317,7 @@
 /* Define if trunc is inlined on x86.  */
 #undef HAVE_X86_INLINE_TRUNC
 
+/* Define if compiler allows add attribute after function declaration.  */
+#undef ATTR_AFTER_FUNC_DECL
+
 #endif
diff --git a/configure b/configure
index 122020db697..c2e33a5c9f1 100755
--- a/configure
+++ b/configure
@@ -9468,6 +9468,35 @@ if test "$pthread_in_libc" = yes; then
 fi
 
 
+# Some symbols that might be auto-generated by the compiler are redefined
+# to internal alias (for instance mempcpy to __mempcpy).  However, if fortify
+# is enabled, the fortify wrapper is define before the alias re-defined and
+# clang warns attribute declaration must precede definition.
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking attribute can declared after function declaration" >&5
+printf %s "checking attribute can declared after function declaration... " >&6; }
+if test ${libc_cv_attr_after_func_decl+y}
+then :
+  printf %s "(cached) " >&6
+else case e in #(
+  e) cat > conftest.c <<EOF
+extern __inline int foo (void) { return 0; };
+extern __typeof (foo) foo __asm__ ("__foo");
+EOF
+libc_cv_attr_after_func_decl=no
+if ${CC-cc} $CFLAGS $CPPFLAGS -fgnu89-inline -Werror conftest.c -c \
+   1>&5 2>&5 ; then
+   libc_cv_attr_after_func_decl=yes
+fi
+rm -rf conftest* ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_attr_after_func_decl" >&5
+printf "%s\n" "$libc_cv_attr_after_func_decl" >&6; }
+if test "$libc_cv_attr_after_func_decl" = yes; then
+   printf "%s\n" "#define ATTR_AFTER_FUNC_DECL 1" >>confdefs.h
+
+fi
+
 ac_config_files="$ac_config_files config.make Makefile"
 
 ac_config_commands="$ac_config_commands default"
diff --git a/configure.ac b/configure.ac
index 14a0f2dee89..1150ce9aac7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2181,6 +2181,26 @@ if test "$pthread_in_libc" = yes; then
 fi
 AC_SUBST(pthread_in_libc)
 
+# Some symbols that might be auto-generated by the compiler are redefined
+# to internal alias (for instance mempcpy to __mempcpy).  However, if fortify
+# is enabled, the fortify wrapper is define before the alias re-defined and
+# clang warns attribute declaration must precede definition.
+AC_CACHE_CHECK([attribute can declared after function declaration],
+	       libc_cv_attr_after_func_decl, [dnl
+cat > conftest.c <<EOF
+extern __inline int foo (void) { return 0; };
+extern __typeof (foo) foo __asm__ ("__foo");
+EOF
+libc_cv_attr_after_func_decl=no
+if ${CC-cc} $CFLAGS $CPPFLAGS -fgnu89-inline -Werror conftest.c -c \
+   1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ; then
+   libc_cv_attr_after_func_decl=yes
+fi
+rm -rf conftest*])
+if test "$libc_cv_attr_after_func_decl" = yes; then
+   AC_DEFINE(ATTR_AFTER_FUNC_DECL)
+fi
+
 AC_CONFIG_FILES([config.make Makefile])
 AC_CONFIG_COMMANDS([default],[[
 case $CONFIG_FILES in *config.make*)
diff --git a/include/string.h b/include/string.h
index c26ca0927ca..59015c7819d 100644
--- a/include/string.h
+++ b/include/string.h
@@ -188,8 +188,13 @@ extern __typeof (strsep) strsep attribute_hidden;
   && !defined NO_MEMPCPY_STPCPY_REDIRECT
 /* Redirect calls to __builtin_mempcpy and __builtin_stpcpy to call
    __mempcpy and __stpcpy if not inlined.  */
+# ifdef ATTR_AFTER_FUNC_DECL
 extern __typeof (mempcpy) mempcpy __asm__ ("__mempcpy");
 extern __typeof (stpcpy) stpcpy __asm__ ("__stpcpy");
+# else
+__asm__ ("mempcpy = __mempcpy");
+__asm__ ("stpcpy = __stpcpy");
+# endif
 #endif
 
 extern void *__memcpy_chk (void *__restrict __dest,
-- 
2.43.0



More information about the Libc-alpha mailing list