Build: Use AC_LINK_IFELSE to handle implicit function declarations

It's more robust in case the compiler allows pre-C99 implicit function
declarations. If an x86 intrinsic is missing and gets treated as
implicit function, the linking step will very probably fail. This
isn't the only way to workaround implicit function declarations but
it might be the simplest and cleanest.

The problem hasn't been observed in the wild.

There are a couple more AC_COMPILE_IFELSE uses in configure.ac.
Of these, Landlock check calls prctl() and in theory could have
the same problem. In practice it doesn't as the check program
looks for several other things too. However, it was changed to
AC_LINK_IFELSE still to look more correct.

Similarly, m4/tuklib_cpucores.m4 and m4/tuklib_physmem.m4 were
updated although they haven't given any trouble either. They
have worked all these years because those check programs rely
on specific headers and types: if headers or types are missing,
compilation will fail. Using the linker makes these checks more
similar to the ones in cmake/tuklib_*.cmake which always link.

(cherry picked from commit 7bb46f2b7b)
This commit is contained in:
Lasse Collin 2024-06-25 14:24:29 +03:00
parent b45270d88f
commit 55bf3f49a8
No known key found for this signature in database
GPG Key ID: 38EE757D69184620
3 changed files with 21 additions and 12 deletions

View File

@ -1010,11 +1010,15 @@ AC_CHECK_DECL([_mm_movemask_epi8],
# #
# If everything above is supported, runtime detection will be used to keep the # If everything above is supported, runtime detection will be used to keep the
# binaries working on systems that don't support the required extensions. # binaries working on systems that don't support the required extensions.
#
# NOTE: Use a check that links and not merely compiles to ensure that
# missing intrinsics don't get accepted with compilers that allow
# implicit function declarations.
AC_MSG_CHECKING([if _mm_clmulepi64_si128 is usable]) AC_MSG_CHECKING([if _mm_clmulepi64_si128 is usable])
AS_IF([test "x$enable_clmul_crc" = xno], [ AS_IF([test "x$enable_clmul_crc" = xno], [
AC_MSG_RESULT([no, --disable-clmul-crc was used]) AC_MSG_RESULT([no, --disable-clmul-crc was used])
], [ ], [
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ AC_LINK_IFELSE([AC_LANG_SOURCE([[
#include <immintrin.h> #include <immintrin.h>
// CLMUL works on older E2K instruction set but it is slow due to emulation. // CLMUL works on older E2K instruction set but it is slow due to emulation.
@ -1117,7 +1121,7 @@ AS_CASE([$enable_sandbox],
# A compile check is done here because some systems have # A compile check is done here because some systems have
# linux/landlock.h, but do not have the syscalls defined # linux/landlock.h, but do not have the syscalls defined
# in order to actually use Linux Landlock. # in order to actually use Linux Landlock.
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ AC_LINK_IFELSE([AC_LANG_SOURCE([[
#include <linux/landlock.h> #include <linux/landlock.h>
#include <sys/syscall.h> #include <sys/syscall.h>
#include <sys/prctl.h> #include <sys/prctl.h>

View File

@ -71,7 +71,7 @@ main(void)
# -lfreebsd-glue when linking and thus in the current form this would # -lfreebsd-glue when linking and thus in the current form this would
# fail on GNU/kFreeBSD. The above test for sched_getaffinity() matches # fail on GNU/kFreeBSD. The above test for sched_getaffinity() matches
# on GNU/kFreeBSD so the test below should never run on that OS. # on GNU/kFreeBSD so the test below should never run on that OS.
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ AC_LINK_IFELSE([AC_LANG_SOURCE([[
#include <sys/param.h> #include <sys/param.h>
#include <sys/cpuset.h> #include <sys/cpuset.h>
@ -92,7 +92,7 @@ main(void)
# #
# We test sysctl() first and intentionally break the sysctl() test on QNX # We test sysctl() first and intentionally break the sysctl() test on QNX
# so that sysctl() is never used on QNX. # so that sysctl() is never used on QNX.
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ AC_LINK_IFELSE([AC_LANG_SOURCE([[
#ifdef __QNX__ #ifdef __QNX__
compile error compile error
#endif #endif
@ -116,7 +116,7 @@ main(void)
} }
]])], [tuklib_cv_cpucores_method=sysctl], [ ]])], [tuklib_cv_cpucores_method=sysctl], [
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ AC_LINK_IFELSE([AC_LANG_SOURCE([[
#include <unistd.h> #include <unistd.h>
int int
main(void) main(void)
@ -133,7 +133,7 @@ main(void)
} }
]])], [tuklib_cv_cpucores_method=sysconf], [ ]])], [tuklib_cv_cpucores_method=sysconf], [
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ AC_LINK_IFELSE([AC_LANG_SOURCE([[
#include <sys/param.h> #include <sys/param.h>
#include <sys/pstat.h> #include <sys/pstat.h>

View File

@ -65,6 +65,11 @@ compile error
# Look for AIX-specific solution before sysconf(), because the test # Look for AIX-specific solution before sysconf(), because the test
# for sysconf() will pass on AIX but won't actually work # for sysconf() will pass on AIX but won't actually work
# (sysconf(_SC_PHYS_PAGES) compiles but always returns -1 on AIX). # (sysconf(_SC_PHYS_PAGES) compiles but always returns -1 on AIX).
#
# NOTE: There is no need to link the check program because it's not calling
# any functions and thus implicit function declarations aren't a problem.
# The unused reference to _system_configuration.physmem might get optimized
# away, and thus the linker might not see that symbol anyway.
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
#include <sys/systemcfg.h> #include <sys/systemcfg.h>
@ -76,7 +81,7 @@ main(void)
} }
]])], [tuklib_cv_physmem_method=aix], [ ]])], [tuklib_cv_physmem_method=aix], [
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ AC_LINK_IFELSE([AC_LANG_SOURCE([[
#include <unistd.h> #include <unistd.h>
int int
main(void) main(void)
@ -88,7 +93,7 @@ main(void)
} }
]])], [tuklib_cv_physmem_method=sysconf], [ ]])], [tuklib_cv_physmem_method=sysconf], [
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ AC_LINK_IFELSE([AC_LANG_SOURCE([[
#ifdef HAVE_SYS_PARAM_H #ifdef HAVE_SYS_PARAM_H
# include <sys/param.h> # include <sys/param.h>
#endif #endif
@ -104,7 +109,7 @@ main(void)
} }
]])], [tuklib_cv_physmem_method=sysctl], [ ]])], [tuklib_cv_physmem_method=sysctl], [
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ AC_LINK_IFELSE([AC_LANG_SOURCE([[
#include <sys/sysinfo.h> #include <sys/sysinfo.h>
#include <machine/hal_sysinfo.h> #include <machine/hal_sysinfo.h>
@ -118,7 +123,7 @@ main(void)
} }
]])], [tuklib_cv_physmem_method=getsysinfo],[ ]])], [tuklib_cv_physmem_method=getsysinfo],[
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ AC_LINK_IFELSE([AC_LANG_SOURCE([[
#include <sys/param.h> #include <sys/param.h>
#include <sys/pstat.h> #include <sys/pstat.h>
@ -133,7 +138,7 @@ main(void)
} }
]])], [tuklib_cv_physmem_method=pstat_getstatic],[ ]])], [tuklib_cv_physmem_method=pstat_getstatic],[
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ AC_LINK_IFELSE([AC_LANG_SOURCE([[
#include <invent.h> #include <invent.h>
int int
main(void) main(void)
@ -150,7 +155,7 @@ main(void)
# different sysinfo() so we must check $host_os. # different sysinfo() so we must check $host_os.
case $host_os in case $host_os in
linux*) linux*)
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ AC_LINK_IFELSE([AC_LANG_SOURCE([[
#include <sys/sysinfo.h> #include <sys/sysinfo.h>
int int
main(void) main(void)