On Fri, Jan 22, 2010 at 02:21:28PM +0100, Paolo Bonzini wrote: > On 01/22/2010 02:35 AM, Eric Blake wrote: > >It would be even slicker to do this without having to recompile (that is, > >rewrite AC_LANG_FUNC_LINK_TRY to use the new logic, rather than making > >AC_CHECK_FUNC call AC_LINK_IFELSE twice). > > Since typeof(__builtin_strfry) gives an error, you'd then have two > compilation for the common case when there is _not_ a corresponding GCC > builtin.
If the common test compiles and links, it doesn't imply that the test for built-in function would also compile and link (e.g. when the function being tested has no built-in implementation), and visa versa (e.g. when built-in implementation exists and -Werror is in effect). So it looks like AC_CHECK_FUNC cannot be implemented using just a single compilation that could cover all cases. > Still, Dmitry's patch is definitely on the right way. You just need to > change the "#ifndef __GNUC__" into a shell test for > "$GCC:$ac_[]_AC_LANG_ABBREV[]_werror_flag" = yes:yes. I'm not sure about $ac_[]_AC_LANG_ABBREV[]_werror_flag, because it is not set when -Werror is included in CFLAGS, and the latter case is more common than the use of AC_LANG_WERROR. If there is a way to check whether the -Werror option is in effect, then the test could avoid second AC_LINK_IFELSE call when it is not needed. Here is 2nd edition of the patch, where "#ifndef __GNUC__" is replaced with the test for $GCC mentioned above (so non-gcc compilers wouldn't be penalized). It also introduces a test for the issue. --- lib/autoconf/c.m4 | 13 +++++++++++++ lib/autoconf/functions.m4 | 8 +++++++- lib/autoconf/lang.m4 | 8 ++++++++ tests/semantics.at | 13 +++++++++++++ 4 files changed, 41 insertions(+), 1 deletions(-) diff --git a/lib/autoconf/c.m4 b/lib/autoconf/c.m4 index 40fdab4..c24204e 100644 --- a/lib/autoconf/c.m4 +++ b/lib/autoconf/c.m4 @@ -183,6 +183,19 @@ choke me ], [return $1 ();])]) +# AC_LANG_FUNC_LINK_TRY_GCC_BUILTIN(C)(FUNCTION) +# ---------------------------------------------- +# Test whether the given function is available as a gcc built-in function. +# +m4_define([AC_LANG_FUNC_LINK_TRY_GCC_BUILTIN(C)], +[AC_LANG_PROGRAM( +[#undef $1 +/* Declare this function with the same prototype as __builtin_$1. + This removes a warning about conflicting types for built-in function $1 */ +__typeof__(__builtin_$1) $1; +__typeof__(__builtin_$1) *f = $1; +], [return f != $1;])]) + # AC_LANG_BOOL_COMPILE_TRY(C)(PROLOGUE, EXPRESSION) # ------------------------------------------------- # Return a program that is valid if EXPRESSION is nonzero. diff --git a/lib/autoconf/functions.m4 b/lib/autoconf/functions.m4 index 24dcf86..8f7bb28 100644 --- a/lib/autoconf/functions.m4 +++ b/lib/autoconf/functions.m4 @@ -47,7 +47,13 @@ m4_define([_AC_CHECK_FUNC_BODY], AC_CACHE_CHECK([for $[]2], [$[]3], [AC_LINK_IFELSE([AC_LANG_FUNC_LINK_TRY($[]2)], [AS_VAR_SET([$[]3], [yes])], - [AS_VAR_SET([$[]3], [no])])]) + [if test "$GCC" = yes; then + AC_LINK_IFELSE([AC_LANG_FUNC_LINK_TRY_GCC_BUILTIN($[]2)], + [AS_VAR_SET([$[]3], [yes])], + [AS_VAR_SET([$[]3], [no])]) + else + AS_VAR_SET([$[]3], [no]) + fi])]) AS_LINENO_POP ])# _AC_CHECK_FUNC_BODY diff --git a/lib/autoconf/lang.m4 b/lib/autoconf/lang.m4 index 98ccf5c..f709633 100644 --- a/lib/autoconf/lang.m4 +++ b/lib/autoconf/lang.m4 @@ -179,6 +179,7 @@ m4_define([AC_LANG_DEFINE], [m4_copy([AC_LANG_PROGRAM($5)], [AC_LANG_PROGRAM($1)])] [m4_copy([AC_LANG_CALL($5)], [AC_LANG_CALL($1)])] [m4_copy([AC_LANG_FUNC_LINK_TRY($5)], [AC_LANG_FUNC_LINK_TRY($1)])] +[m4_copy([AC_LANG_FUNC_LINK_TRY_GCC_BUILTIN($5)], [AC_LANG_FUNC_LINK_TRY_GCC_BUILTIN($1)])] [m4_copy([AC_LANG_BOOL_COMPILE_TRY($5)], [AC_LANG_BOOL_COMPILE_TRY($1)])] [m4_copy([AC_LANG_INT_SAVE($5)], [AC_LANG_INT_SAVE($1)])] [m4_copy([_AC_LANG_IO_PROGRAM($5)], [_AC_LANG_IO_PROGRAM($1)])])]) @@ -269,6 +270,13 @@ AC_DEFUN([AC_LANG_FUNC_LINK_TRY], _AC_LANG_DISPATCH([$0], _AC_LANG, $@)]) +# AC_LANG_FUNC_LINK_TRY_GCC_BUILTIN(FUNCTION, TYPE) +# ------------------------------------------------- +AC_DEFUN([AC_LANG_FUNC_LINK_TRY_GCC_BUILTIN], +[m4_ifval([$1], [], [m4_warn([syntax], [$0: no function given])])dnl +_AC_LANG_DISPATCH([$0], _AC_LANG, $@)]) + + # AC_LANG_BOOL_COMPILE_TRY(PROLOGUE, EXPRESSION) # ---------------------------------------------- # Produce a program that compiles with success iff the boolean EXPRESSION diff --git a/tests/semantics.at b/tests/semantics.at index 9aaffc3..213f067 100644 --- a/tests/semantics.at +++ b/tests/semantics.at @@ -133,6 +133,19 @@ AT_CHECK_MACRO([AC_CHECK_FUNCS], ])]) +# AC_CHECK_FUNCS after AC_LANG_WERROR +# ----------------------------------- +# Check that it performs the correct actions: +# Must define HAVE_PRINTF, but not HAVE_AUTOCONF_FTNIRP +AT_CHECK_MACRO([AC_CHECK_FUNCS after AC_LANG_WERROR], +[AC_LANG_WERROR +AC_CHECK_FUNCS(printf autoconf_ftnirp)], +[AT_CHECK_DEFINES( +[/* #undef HAVE_AUTOCONF_FTNIRP */ +#define HAVE_PRINTF 1 +])]) + + # AC_REPLACE_FUNCS # ---------------- # Check that it performs the correct actions: autoconf_ftnirp.c must -- ldv
pgpSVKSUR9fYO.pgp
Description: PGP signature