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

Attachment: pgpSVKSUR9fYO.pgp
Description: PGP signature

Reply via email to