## Checking for declared symbols. ##
## ------------------------------- ##
-
-# _AC_UNDECLARED_WARNING
+# _AC_UNDECLARED_BUILTIN
# ----------------------
-# Set ac_[]_AC_LANG_ABBREV[]_decl_warn_flag=yes if the compiler uses a warning,
-# not a more-customary error, to report some undeclared identifiers. Fail when
-# an affected compiler warns also on valid input. _AC_PROG_PREPROC_WORKS_IFELSE
-# solves a related problem.
-AC_DEFUN([_AC_UNDECLARED_WARNING],
-[# The Clang compiler raises a warning for an undeclared identifier that matches
-# a compiler builtin function. All extant Clang versions are affected, as of
-# Clang 3.6.0. Test a builtin known to every version. This problem affects the
-# C and Objective C languages, but Clang does report an error under C++ and
-# Objective C++.
-#
-# Passing -fno-builtin to the compiler would suppress this problem. That
-# strategy would have the advantage of being insensitive to stray warnings, but
-# it would make tests less realistic.
-AC_CACHE_CHECK([how $[]_AC_CC[] reports undeclared, standard C functions],
-[ac_cv_[]_AC_LANG_ABBREV[]_decl_report],
-[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [(void) strchr;])],
- [AS_IF([test -s conftest.err], [dnl
- # For AC_CHECK_DECL to react to warnings, the compiler must be silent on
- # valid AC_CHECK_DECL input. No library function is consistently available
- # on freestanding implementations, so test against a dummy declaration.
- # Include always-available headers on the off chance that they somehow
- # elicit warnings.
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([dnl
-#include <float.h>
+# Set ac_[]_AC_LANG_ABBREV[]_undeclared_builtin_options to any options
+# needed to make the compiler issue a hard error, not a warning, when
+# an undeclared function is used whose declaration happens to be
+# built into the compiler (e.g. 'strchr' is often known in advance to
+# the C compiler). These options should not cause any other unrelated
+# warnings to become errors. If no such options can be found, or if
+# they make the compiler error out on a correct program of the form
+# used by AC_CHECK_DECL, report failure.
+AC_DEFUN([_AC_UNDECLARED_BUILTIN],
+[AC_CACHE_CHECK(
+ [for $[]_AC_CC options needed to detect all undeclared functions],
+ [ac_cv_[]_AC_LANG_ABBREV[]_undeclared_builtin_options],
+ [ac_save_CFLAGS=$CFLAGS
+ ac_cv_[]_AC_LANG_ABBREV[]_undeclared_builtin_options='cannot detect'
+ for ac_arg in '' -fno-builtin; do
+ CFLAGS="$ac_save_CFLAGS $ac_arg"
+ # This test program should *not* compile successfully.
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [(void) strchr;])],
+ [],
+ [# This test program should compile successfully.
+ # No library function is consistently available on
+ # freestanding implementations, so test against a dummy
+ # declaration. Include always-available headers on the
+ # off chance that they somehow elicit warnings.
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+[[#include <float.h>
#include <limits.h>
#include <stdarg.h>
#include <stddef.h>
-extern void ac_decl (int, char *);],
-[@%:@ifdef __cplusplus
- (void) ac_decl ((int) 0, (char *) 0);
- (void) ac_decl;
-@%:@else
+extern void ac_decl (int, char *);
+]],
+[[(void) ac_decl (0, (char *) 0);
(void) ac_decl;
-@%:@endif
-])],
- [AS_IF([test -s conftest.err],
- [AC_MSG_FAILURE([cannot detect from compiler exit status or warnings])],
- [ac_cv_[]_AC_LANG_ABBREV[]_decl_report=warning])],
- [AC_MSG_FAILURE([cannot compile a simple declaration test])])],
- [AC_MSG_FAILURE([compiler does not report undeclared identifiers])])],
- [ac_cv_[]_AC_LANG_ABBREV[]_decl_report=error])])
-
-case $ac_cv_[]_AC_LANG_ABBREV[]_decl_report in
- warning) ac_[]_AC_LANG_ABBREV[]_decl_warn_flag=yes ;;
- *) ac_[]_AC_LANG_ABBREV[]_decl_warn_flag= ;;
-esac
-])# _AC_UNDECLARED_WARNING
+]])],
+ [AS_IF([test x"$ac_arg" = x],
+ [ac_cv_[]_AC_LANG_ABBREV[]_undeclared_builtin_options='none needed'],
+ [ac_cv_[]_AC_LANG_ABBREV[]_undeclared_builtin_options=$ac_arg])
+ break],
+ [])])
+ done
+ CFLAGS=$ac_save_CFLAGS
+ ])
+ AS_CASE([$ac_cv_[]_AC_LANG_ABBREV[]_undeclared_builtin_options],
+ ['cannot detect'],
+ [AC_MSG_FAILURE([cannot make $[]_AC_CC report undeclared builtins])],
+ ['none needed'],
+ [ac_[]_AC_LANG_ABBREV[]_undeclared_builtin_options=''],
+ [ac_[]_AC_LANG_ABBREV[]_undeclared_builtin_options=$ac_cv_[]_AC_LANG_ABBREV[]_undeclared_builtin_options])
+])
# _AC_CHECK_DECL_BODY
# -------------------
# Shell function body for AC_CHECK_DECL.
+# If we are compiling C, just refer to the name of the function, so we
+# don't implicitly declare it. However, if we are compiling C++,
+# `(void) function_name;' won't work when function_name has more than one
+# overload, we need to fabricate a function call. Fortunately, there is
+# no such thing as an implicit function declaration in C++.
+# If the function is defined as a macro, we cannot verify its signature
+# without calling it, and it might not expand to a construct that's valid
+# as the only statement in a function body; just report it as available.
m4_define([_AC_CHECK_DECL_BODY],
[ AS_LINENO_PUSH([$[]1])
- # Initialize each $ac_[]_AC_LANG_ABBREV[]_decl_warn_flag once.
- AC_DEFUN([_AC_UNDECLARED_WARNING_]_AC_LANG_ABBREV,
- [_AC_UNDECLARED_WARNING])dnl
- AC_REQUIRE([_AC_UNDECLARED_WARNING_]_AC_LANG_ABBREV)dnl
- [as_decl_name=`echo $][2|sed 's/ *(.*//'`]
- [as_decl_use=`echo $][2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`]
- AC_CACHE_CHECK([whether $as_decl_name is declared], [$[]3],
- [ac_save_werror_flag=$ac_[]_AC_LANG_ABBREV[]_werror_flag
- ac_[]_AC_LANG_ABBREV[]_werror_flag="$ac_[]_AC_LANG_ABBREV[]_decl_warn_flag$ac_[]_AC_LANG_ABBREV[]_werror_flag"
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([$[]4],
-[@%:@ifndef $[]as_decl_name
-@%:@ifdef __cplusplus
- (void) $[]as_decl_use;
-@%:@else
- (void) $[]as_decl_name;
-@%:@endif
-@%:@endif
-])],
+ as_decl_name=`echo $[]2|sed 's/ *(.*//'`
+ AC_CACHE_CHECK([whether $][as_decl_name is declared], [$[]3],
+ [as_decl_use=`echo $[]2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
+ AS_VAR_COPY([ac_save_FLAGS], [$[]6])
+ AS_VAR_APPEND([$[]6], [" $[]5"])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$][4]],
+[[#ifndef $][as_decl_name
+#ifdef __cplusplus
+ (void) $][as_decl_use;
+#else
+ (void) $][as_decl_name;
+#endif
+#endif
+]])],
[AS_VAR_SET([$[]3], [yes])],
[AS_VAR_SET([$[]3], [no])])
- ac_[]_AC_LANG_ABBREV[]_werror_flag=$ac_save_werror_flag])
+ AS_VAR_COPY([$[]6], [ac_save_FLAGS])
+])
AS_LINENO_POP
])# _AC_CHECK_DECL_BODY
# -------------------------------------------------------
# Check whether SYMBOL (a function, variable, or constant) is declared.
AC_DEFUN([AC_CHECK_DECL],
-[AC_REQUIRE_SHELL_FN([ac_fn_]_AC_LANG_ABBREV[_check_decl],
- [AS_FUNCTION_DESCRIBE([ac_fn_]_AC_LANG_ABBREV[_check_decl],
- [LINENO SYMBOL VAR INCLUDES],
+[AC_REQUIRE_SHELL_FN([ac_fn_check_decl],
+ [AS_FUNCTION_DESCRIBE([ac_fn_check_decl],
+ [LINENO SYMBOL VAR INCLUDES EXTRA-OPTIONS FLAG-VAR],
[Tests whether SYMBOL is declared in INCLUDES, setting cache variable
- VAR accordingly.])],
+ VAR accordingly. Pass EXTRA-OPTIONS to the compiler, using FLAG-VAR.])],
[_$0_BODY])]dnl
+dnl Initialize each $ac_[]_AC_LANG_ABBREV[]_undeclared_builtin_options once.
+[AC_DEFUN([_AC_UNDECLARED_BUILTIN_]_AC_LANG_ABBREV,
+ [_AC_UNDECLARED_BUILTIN])]dnl
+[AC_REQUIRE([_AC_UNDECLARED_BUILTIN_]_AC_LANG_ABBREV)]dnl
[AS_VAR_PUSHDEF([ac_Symbol], [ac_cv_have_decl_$1])]dnl
-[ac_fn_[]_AC_LANG_ABBREV[]_check_decl ]dnl
-["$LINENO" "$1" "ac_Symbol" "AS_ESCAPE([AC_INCLUDES_DEFAULT([$4])], [""])"
-AS_VAR_IF([ac_Symbol], [yes], [$2], [$3])
-AS_VAR_POPDEF([ac_Symbol])dnl
-])# AC_CHECK_DECL
+[ac_fn_check_decl ]dnl
+["$LINENO" "$1" "ac_Symbol" "AS_ESCAPE([AC_INCLUDES_DEFAULT([$4])], [""])" ]dnl
+["$ac_[]_AC_LANG_ABBREV[]_undeclared_builtin_options" "_AC_LANG_PREFIX[]FLAGS"]
+[AS_VAR_IF([ac_Symbol], [yes], [$2], [$3])]dnl
+[AS_VAR_POPDEF([ac_Symbol])]dnl
+)# AC_CHECK_DECL
# _AC_CHECK_DECLS(SYMBOL, ACTION-IF_FOUND, ACTION-IF-NOT-FOUND,
# AC_CHECK_DECLS
# --------------
-# For the benefit of _AC_UNDECLARED_WARNING compilers, these INCLUDES sections
-# should not elicit warnings.
+# Check that it performs the correct actions:
AT_CHECK_MACRO([AC_CHECK_DECLS],
[[AC_CHECK_DECLS([yes, no, myenum, mystruct, myfunc, mymacro1, mymacro2],,,
[[extern int yes;
extern int myfunc();
#define mymacro1(arg) arg
#define mymacro2]])
- # Clang reports a warning for an undeclared builtin.
- AC_CHECK_DECLS([strerror],,, [[]])
+ # Ensure we can detect missing declarations of functions whose
+ # signature may be built into the compiler.
+ AC_CHECK_DECLS([memcpy, strchr, strerror],,, [[]])
# The difference in space-before-open-paren is intentional.
AC_CHECK_DECLS([basenam (char *), dirnam(char *),
moreargs (char, short, int, long, void *, char *, float, double)],,,
[AT_CHECK_DEFINES(
[#define HAVE_DECL_BASENAM 1
#define HAVE_DECL_DIRNAM 0
+#define HAVE_DECL_MEMCPY 0
#define HAVE_DECL_MOREARGS 1
#define HAVE_DECL_MYENUM 1
#define HAVE_DECL_MYFUNC 1
#define HAVE_DECL_MYMACRO2 1
#define HAVE_DECL_MYSTRUCT 1
#define HAVE_DECL_NO 0
+#define HAVE_DECL_STRCHR 0
#define HAVE_DECL_STRERROR 0
#define HAVE_DECL_YES 1
])])