[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: AC_CHECK_DECLS vs. Clang
From: |
Noah Misch |
Subject: |
Re: AC_CHECK_DECLS vs. Clang |
Date: |
Mon, 13 Apr 2015 21:12:52 -0400 |
User-agent: |
Mutt/1.5.23 (2014-03-12) |
On Sun, Mar 08, 2015 at 12:13:44AM -0500, Noah Misch wrote:
> The Clang compiler furnishes implicit declarations for built-in functions,
> even when the identifier in question is not used as a function designator.
> This thwarts AC_CHECK_DECLS:
>
> configure:11565: checking whether strlcpy is declared
> configure:11565: clang -c -Wall -Wmissing-prototypes -Wpointer-arith
> -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute
> -Wformat-security -fno-strict-aliasing -fwrapv -g -O2 -D_GNU_SOURCE
> -I/usr/include/libxml2 conftest.c >&5
> conftest.c:166:10: warning: implicitly declaring library function 'strlcpy'
> with type 'unsigned long (char *, const char *, unsigned long)'
> (void) strlcpy;
> ^
> conftest.c:166:10: note: please include the header <string.h> or explicitly
> provide a declaration for 'strlcpy'
> 1 warning generated.
> configure:11565: $? = 0
> configure:11565: result: yes
>
>
> Full config.log:
> http://buildfarm.postgresql.org/cgi-bin/show_stage_log.pl?nm=treepie&dt=2015-03-07%2006%3A22%3A38&stg=config
>
> Clang has always behaved this way, but strlcpy() and strlcat() were unaffected
> until Clang 3.0 added them as builtins. To fix this, I plan to introduce
> ac_c_decl_warn_flag by analogy to ac_c_preproc_warn_flag. With no explicit
> declarations, a typical compiler (ac_c_decl_warn_flag='') reports an error for
> "(void) strchr;". Clang (ac_c_decl_warn_flag=yes) reports a warning, but
> adding a declaration silences the warning. A compiler that emits some warning
> with or without a declaration is unusable.
Here is the patch. There's a risk that incidental warnings will make
AC_CHECK_DECL wrongly report a declaration missing. If, for example, an
AC_CHECK_DECL test includes a header that elicits a deprecation warning, that
test will report any declaration missing. The Autoconf test suite does pass
under "clang -Weverything -Wno-unused-macros -Wno-main" or "clang -Wno-main".
"-Wno-unused-macros" suppresses warnings about unused confdefs.h macros like
PACKAGE_URL, warnings which would otherwise snag on one of the new sanity
checks. (Unrelated to AC_CHECK_DECL, the "C unit tests" group needs
"-Wno-main".) I considered -fno-builtin instead of checking for warnings, but
the loss of realism outweighs the benefit of mitigating this risk.
The new code caches its test results. _AC_PROG_PREPROC_WORKS_IFELSE, which
inspired the new code, does not cache. Did I overlook a good reason for not
caching the results of tests like these?
I manually tested with C, C++, Objective C and Objective C++ languages.
Thanks,
nm
commit aaf9aba (HEAD, master)
Author: Noah Misch <address@hidden>
AuthorDate: Mon Apr 13 01:38:15 2015 -0400
Commit: Noah Misch <address@hidden>
CommitDate: Mon Apr 13 01:38:15 2015 -0400
AC_CHECK_DECL, AC_CHECK_DECLS: port to the Clang compiler
* lib/autoconf/general.m4 (_AC_UNDECLARED_WARNING): New macro.
(_AC_CHECK_DECL_BODY): Call it once per language; treat warnings as
errors when its verdict indicates that.
* tests/semantics.at (AC_CHECK_DECLS): Add a macro call that relies on
the new semantics. Avoid -Wmissing-variable-declarations warnings.
* doc/autoconf.texi (Generic Declarations): Document the implications.
* NEWS: Mention this change.
diff --git a/NEWS b/NEWS
index 2df5a80..f691179 100644
--- a/NEWS
+++ b/NEWS
@@ -61,6 +61,9 @@ GNU Autoconf NEWS - User visible changes.
- AC_USE_SYSTEM_EXTENSIONS now enables more system extensions on HP-UX,
MINIX 3, and OS X.
+- AC_CHECK_DECL and AC_CHECK_DECLS can now report missing declarations for
+ functions that are also Clang compiler builtins.
+
- AC_FUNC_VFORK now checks for the signal-handling bug in Solaris 2.4 'vfork'.
Formerly, it ignored this bug, so that Emacs could use some tricky
code on that platform. Solaris 2.4 has not been supported since
diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index d9e833d..350855b 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -6315,6 +6315,12 @@ parentheses for types which can be zero-initialized:
AC_CHECK_DECL([basename(char *)])
@end example
+Some compilers don't indicate every missing declaration by the error
+status. This macro checks the standard error from such compilers and
+considers a declaration missing if any warnings have been reported. For
+most compilers, though, warnings do not affect this macro's outcome
+unless @code{AC_LANG_WERROR} is also specified.
+
This macro caches its result in the @address@hidden
variable, with characters not suitable for a variable name mapped to
underscores.
@@ -6375,6 +6381,12 @@ You fall into the second category only in extreme
situations: either
your files may be used without being configured, or they are used during
the configuration. In most cases the traditional approach is enough.
+Some compilers don't indicate every missing declaration by the error
+status. This macro checks the standard error from such compilers and
+considers a declaration missing if any warnings have been reported. For
+most compilers, though, warnings do not affect this macro's outcome
+unless @code{AC_LANG_WERROR} is also specified.
+
This macro caches its results in @address@hidden
variables, with characters not suitable for a variable name mapped to
underscores.
diff --git a/lib/autoconf/general.m4 b/lib/autoconf/general.m4
index 2d1a291..09896e2 100644
--- a/lib/autoconf/general.m4
+++ b/lib/autoconf/general.m4
@@ -2864,15 +2864,72 @@ AC_DEFUN([AC_CHECK_FILES],
## ------------------------------- ##
+# _AC_UNDECLARED_WARNING
+# ----------------------
+# 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>
+#include <limits.h>
+#include <stdarg.h>
+#include <stddef.h>
+extern void ac_decl (int, char *);],
address@hidden:@ifdef __cplusplus
+ (void) ac_decl ((int) 0, (char *) 0);
+ (void) ac_decl;
address@hidden:@else
+ (void) ac_decl;
address@hidden:@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
+
# _AC_CHECK_DECL_BODY
# -------------------
# Shell function body for AC_CHECK_DECL.
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_COMPILE_IFELSE([AC_LANG_PROGRAM([$[]4],
+ [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],
address@hidden:@ifndef $[]as_decl_name
@%:@ifdef __cplusplus
(void) $[]as_decl_use;
@@ -2883,6 +2940,7 @@ m4_define([_AC_CHECK_DECL_BODY],
])],
[AS_VAR_SET([$[]3], [yes])],
[AS_VAR_SET([$[]3], [no])])])
+ ac_[]_AC_LANG_ABBREV[]_werror_flag=$ac_save_werror_flag
AS_LINENO_POP
])# _AC_CHECK_DECL_BODY
diff --git a/tests/semantics.at b/tests/semantics.at
index a7abd52..1294545 100644
--- a/tests/semantics.at
+++ b/tests/semantics.at
@@ -101,15 +101,18 @@ esac
# AC_CHECK_DECLS
# --------------
-# Check that it performs the correct actions:
+# For the benefit of _AC_UNDECLARED_WARNING compilers, these INCLUDES sections
+# should not elicit warnings.
AT_CHECK_MACRO([AC_CHECK_DECLS],
[[AC_CHECK_DECLS([yes, no, myenum, mystruct, myfunc, mymacro1, mymacro2],,,
- [[int yes = 1;
+ [[extern int yes;
enum { myenum };
- struct { int x[20]; } mystruct;
+ extern struct { int x[20]; } mystruct;
extern int myfunc();
#define mymacro1(arg) arg
#define mymacro2]])
+ # Clang reports a warning for an undeclared builtin.
+ AC_CHECK_DECLS([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)]],,,
@@ -148,6 +151,7 @@ AT_CHECK_MACRO([AC_CHECK_DECLS],
#define HAVE_DECL_MYMACRO2 1
#define HAVE_DECL_MYSTRUCT 1
#define HAVE_DECL_NO 0
+#define HAVE_DECL_STRERROR 0
#define HAVE_DECL_YES 1
])])
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: AC_CHECK_DECLS vs. Clang,
Noah Misch <=