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

H.J. Lu hjl.tools@gmail.com
Fri Oct 31 23:37:09 GMT 2025


On Sat, Nov 1, 2025 at 4:03 AM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
> 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
>

LGTM.

Reviewed-by: H.J. Lu <hjl.tools@gmail.com>

Thanks.

-- 
H.J.


More information about the Libc-alpha mailing list