CMake: Fix three checks if building with -flto
commit1591747bf692d10c3b2fd92c9dc8ba931626fd84
authorLasse Collin <lasse.collin@tukaani.org>
Mon, 24 Jun 2024 19:41:10 +0000 (24 22:41 +0300)
committerLasse Collin <lasse.collin@tukaani.org>
Fri, 6 Sep 2024 16:21:25 +0000 (6 19:21 +0300)
tree02e2458d57a3631bfeafe0ddd0cda51cd3afb895
parentcc386f4ff4b87ff895fbc30fd3b13ee6e6152ace
CMake: Fix three checks if building with -flto

In CMake, check_c_source_compiles() always links too. With
link-time optimization, unused functions may get omitted if
main() doesn't depend on them. Consider the following which
tries to check if somefunction() is available when <someheader.h>
has been included:

    #include <someheader.h>
    int foo(void) { return somefunction(); }
    int main(void) { return 0; }

LTO may omit foo() completely because the program as a whole doesn't
need it and then the program will link even if the symbol somefunction
isn't available in libc or other library being linked in, and then
the test may pass when it shouldn't.

What happens if <someheader.h> doesn't declare somefunction()?
Shouldn't the test fail in the compilation phase already? It should
but many compilers don't follow the C99 and later standards that
prohibit implicit function declarations. Instead such compilers
assume that somefunction() exists, compilation succeeds (with a
warning), and then linker with LTO omits the call to somefunction().

Change the tests so that they are part of main(). If compiler accepts
implicitly declared functions, LTO cannot omit them because it has to
assume that they might have side effects and thus linking will fail.
On the other hand, if the functions/intrinsics being used are supported,
they might get optimized away but in that case it's fine because they
really are supported.

It is fine to use __attribute__((target(...))) for main(). At least
it works with GCC 4.9 to 14.1 on x86-64.

Reported-by: Sam James <sam@gentoo.org>
(cherry picked from commit 114cba69dbb96003e676c8c87a2e9943b12d065f)
CMakeLists.txt