From 7bb46f2b7b3989c1b589a247a251470f65e91cda Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Tue, 25 Jun 2024 14:24:29 +0300 Subject: [PATCH] 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. --- configure.ac | 8 ++++++-- m4/tuklib_cpucores.m4 | 8 ++++---- m4/tuklib_physmem.m4 | 17 +++++++++++------ 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/configure.ac b/configure.ac index aa08c37e..cb6eaaa3 100644 --- a/configure.ac +++ b/configure.ac @@ -1015,11 +1015,15 @@ AC_CHECK_DECL([_mm_movemask_epi8], # # If everything above is supported, runtime detection will be used to keep the # 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]) AS_IF([test "x$enable_clmul_crc" = xno], [ AC_MSG_RESULT([no, --disable-clmul-crc was used]) ], [ - AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ + AC_LINK_IFELSE([AC_LANG_SOURCE([[ #include // CLMUL works on older E2K instruction set but it is slow due to emulation. @@ -1131,7 +1135,7 @@ AS_CASE([$enable_sandbox], # A compile check is done here because some systems have # linux/landlock.h, but do not have the syscalls defined # in order to actually use Linux Landlock. - AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ + AC_LINK_IFELSE([AC_LANG_SOURCE([[ #include #include #include diff --git a/m4/tuklib_cpucores.m4 b/m4/tuklib_cpucores.m4 index a228a8fb..928ef344 100644 --- a/m4/tuklib_cpucores.m4 +++ b/m4/tuklib_cpucores.m4 @@ -71,7 +71,7 @@ main(void) # -lfreebsd-glue when linking and thus in the current form this would # fail on GNU/kFreeBSD. The above test for sched_getaffinity() matches # 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 #include @@ -92,7 +92,7 @@ main(void) # # We test sysctl() first and intentionally break the sysctl() test on QNX # so that sysctl() is never used on QNX. -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ +AC_LINK_IFELSE([AC_LANG_SOURCE([[ #ifdef __QNX__ compile error #endif @@ -116,7 +116,7 @@ main(void) } ]])], [tuklib_cv_cpucores_method=sysctl], [ -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ +AC_LINK_IFELSE([AC_LANG_SOURCE([[ #include int main(void) @@ -133,7 +133,7 @@ main(void) } ]])], [tuklib_cv_cpucores_method=sysconf], [ -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ +AC_LINK_IFELSE([AC_LANG_SOURCE([[ #include #include diff --git a/m4/tuklib_physmem.m4 b/m4/tuklib_physmem.m4 index b5e0b1ad..4bffe858 100644 --- a/m4/tuklib_physmem.m4 +++ b/m4/tuklib_physmem.m4 @@ -65,6 +65,11 @@ compile error # Look for AIX-specific solution before sysconf(), because the test # for sysconf() will pass on AIX but won't actually work # (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([[ #include @@ -76,7 +81,7 @@ main(void) } ]])], [tuklib_cv_physmem_method=aix], [ -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ +AC_LINK_IFELSE([AC_LANG_SOURCE([[ #include int main(void) @@ -88,7 +93,7 @@ main(void) } ]])], [tuklib_cv_physmem_method=sysconf], [ -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ +AC_LINK_IFELSE([AC_LANG_SOURCE([[ #ifdef HAVE_SYS_PARAM_H # include #endif @@ -104,7 +109,7 @@ main(void) } ]])], [tuklib_cv_physmem_method=sysctl], [ -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ +AC_LINK_IFELSE([AC_LANG_SOURCE([[ #include #include @@ -118,7 +123,7 @@ main(void) } ]])], [tuklib_cv_physmem_method=getsysinfo],[ -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ +AC_LINK_IFELSE([AC_LANG_SOURCE([[ #include #include @@ -133,7 +138,7 @@ main(void) } ]])], [tuklib_cv_physmem_method=pstat_getstatic],[ -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ +AC_LINK_IFELSE([AC_LANG_SOURCE([[ #include int main(void) @@ -150,7 +155,7 @@ main(void) # different sysinfo() so we must check $host_os. case $host_os in linux*) - AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ + AC_LINK_IFELSE([AC_LANG_SOURCE([[ #include int main(void)