[PATCH] config: change PAC_FUNC_NEEDS_DECL to check by assignment
The old method attempts to create a failed compile when the function *is* already declared, by creating an incompatible declaration. That is insufficient with clang-3.2, which only warns in case of incompatible redeclaration of a library function: conftest.c:44:5: warning: incompatible redeclaration of library function 'strncmp' int strncmp(double, int, double, const char *); ^ /usr/include/string.h:143:12: note: 'strncmp' is a builtin with type 'int (const char *, const char *, size_t)' extern int strncmp (const char *__s1, const char *__s2, size_t __n) ^ 1 warning generated. Instead, we take the opposite approach, generating a failed compile when the library function has *not* been declared in the header. void (*fptr)(void) = (void(*)(void))strncmp; Signed-off-by: Jed Brown <[email protected]> --- confdb/aclocal_cc.m4 | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/confdb/aclocal_cc.m4 b/confdb/aclocal_cc.m4 index 7a92a8a..10964e1 100644 --- a/confdb/aclocal_cc.m4 +++ b/confdb/aclocal_cc.m4 @@ -1205,25 +1205,22 @@ dnl Sets 'NEEDS_<funcname>_DECL' if 'funcname' is not declared by the dnl headerfiles. dnl dnl Approach: -dnl Try to compile a program with the function, but passed with an incorrect -dnl calling sequence. If the compilation fails, then the declaration -dnl is provided within the header files. If the compilation succeeds, -dnl the declaration is required. +dnl Attempt to assign library function to function pointer. If the function +dnl is not declared in a header, this will fail. Use a non-static global so +dnl the compiler does not warn about an unused variable. dnl -dnl We use a 'double' as the first argument to try and catch varargs -dnl routines that may use an int or pointer as the first argument. +dnl Simply calling the function is not enough because C89 compilers allow +dnl calls to implicitly-defined functions. Re-declaring a library function +dnl with an incompatible prototype is also not sufficient because some +dnl compilers (notably clang-3.2) only produce a warning in this case. dnl -dnl There is one difficulty - if the compiler has been instructed to -dnl fail on implicitly defined functions, then this test will always -dnl fail. -dnl dnl D*/ AC_DEFUN([PAC_FUNC_NEEDS_DECL],[ AC_CACHE_CHECK([whether $2 needs a declaration], pac_cv_func_decl_$2,[ AC_TRY_COMPILE([$1 -int $2(double, int, double, const char *);],[int a=$2(1.0,27,1.0,"foo");], -pac_cv_func_decl_$2=yes,pac_cv_func_decl_$2=no)]) +void (*fptr)(void) = (void(*)(void))$2;],[], +pac_cv_func_decl_$2=no,pac_cv_func_decl_$2=yes)]) if test "$pac_cv_func_decl_$2" = "yes" ; then changequote(<<,>>)dnl define(<<PAC_FUNC_NAME>>, translit(NEEDS_$2_DECL, [a-z *], [A-Z__]))dnl -- 1.8.2.3
participants (1)
-
Jed Brown