]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
fix: LTO is disabled if `-fno-lto` is used (#1700)
authorKristian Sloth Lauszus <lauszus@gmail.com>
Sat, 14 Mar 2026 09:50:26 +0000 (10:50 +0100)
committerGitHub <noreply@github.com>
Sat, 14 Mar 2026 09:50:26 +0000 (10:50 +0100)
If `-flto` is followered by `-fno-lto`, then LTO will be disabled

On the other hand if `-fno-lto` is followered by `-flto`, then LTO will be enabled

src/ccache/argprocessing.cpp
test/suites/direct.bash

index 6711e29c2a26f3ba0dcede5f53c4b68576b3218a..8d5471c86a1555af498a26864f689ad5cb20b5a4 100644 (file)
@@ -951,12 +951,20 @@ process_option_arg(const Context& ctx,
     return Statistic::none;
   }
 
+  // LTO can be enabled with -flto[=n]
   if (arg == "-flto" || arg.starts_with("-flto=")) {
     args_info.using_lto = true;
     state.add_common_arg(args[i]);
     return Statistic::none;
   }
 
+  // LTO can be disabled with -fno-lto
+  if (arg == "-fno-lto") {
+    args_info.using_lto = false;
+    state.add_common_arg(args[i]);
+    return Statistic::none;
+  }
+
   // -Zs is MSVC's -fsyntax-only equivalent
   if (arg == "-fsyntax-only" || arg == "-Zs") {
     args_info.expect_output_obj = false;
index c1d69d458a41473fdf1dc0967085a916f7f37bb7..8964a7d0b3d737d845d9e767ca1c5f86dd04bf10 100644 (file)
@@ -714,6 +714,94 @@ EOF
         fi
     fi
 
+    # -------------------------------------------------------------------------
+    TEST "-fstack-usage with -flto -fno-lto"
+
+    cat <<EOF >main.c
+extern int test();
+int main() { return test(); }
+EOF
+
+    cat <<EOF >code.c
+int test() { return 0; }
+EOF
+
+    if $COMPILER -c -fstack-usage -flto -fno-lto main.c >/dev/null 2>&1; then
+        $CCACHE_COMPILE -c -fstack-usage -flto -fno-lto main.c
+        $CCACHE_COMPILE -c -fstack-usage -flto -fno-lto code.c
+        $CCACHE_COMPILE -o output -fstack-usage -flto -fno-lto main.o code.o
+        expect_stat called_for_link 1
+        expect_stat direct_cache_hit 0
+        expect_stat preprocessed_cache_hit 0
+        expect_stat cache_miss 2
+        expect_exists main.su
+        expect_exists code.su
+        expect_missing output.ltrans0.ltrans.su
+
+        rm main.su
+        rm code.su
+
+        $CCACHE_COMPILE -c -fstack-usage -flto -fno-lto main.c
+        $CCACHE_COMPILE -c -fstack-usage -flto -fno-lto code.c
+        $CCACHE_COMPILE -o output -fstack-usage -flto -fno-lto main.o code.o
+        expect_stat called_for_link 2
+        expect_stat direct_cache_hit 2
+        expect_stat preprocessed_cache_hit 0
+        expect_stat cache_miss 2
+        expect_exists main.su
+        expect_exists code.su
+        expect_missing output.ltrans0.ltrans.su
+    fi
+
+    # -------------------------------------------------------------------------
+    TEST "-fstack-usage with -fno-lto -flto"
+
+    cat <<EOF >main.c
+extern int test();
+int main() { return test(); }
+EOF
+
+    cat <<EOF >code.c
+int test() { return 0; }
+EOF
+
+    if $COMPILER -c -fstack-usage -fno-lto -flto main.c >/dev/null 2>&1; then
+        $CCACHE_COMPILE -c -fstack-usage -fno-lto -flto main.c
+        $CCACHE_COMPILE -c -fstack-usage -fno-lto -flto code.c
+        $CCACHE_COMPILE -o output -fstack-usage -fno-lto -flto main.o code.o
+        expect_stat called_for_link 1
+        expect_stat direct_cache_hit 0
+        expect_stat preprocessed_cache_hit 0
+        expect_stat cache_miss 2
+        expect_missing main.su
+        expect_missing code.su
+
+        # clang does not produce .su files
+        if [[ "$(basename "$COMPILER")" != clang* ]]; then
+            expect_exists output.ltrans0.ltrans.su
+            expect_contains output.ltrans0.ltrans.su main.c
+            expect_contains output.ltrans0.ltrans.su code.c
+            rm output.ltrans0.ltrans.su
+        fi
+
+        $CCACHE_COMPILE -c -fstack-usage -fno-lto -flto main.c
+        $CCACHE_COMPILE -c -fstack-usage -fno-lto -flto code.c
+        $CCACHE_COMPILE -o output -fstack-usage -fno-lto -flto main.o code.o
+        expect_stat called_for_link 2
+        expect_stat direct_cache_hit 2
+        expect_stat preprocessed_cache_hit 0
+        expect_stat cache_miss 2
+        expect_missing main.su
+        expect_missing code.su
+
+        # clang does not produce .su files
+        if [[ "$(basename "$COMPILER")" != clang* ]]; then
+            expect_exists output.ltrans0.ltrans.su
+            expect_contains output.ltrans0.ltrans.su main.c
+            expect_contains output.ltrans0.ltrans.su code.c
+        fi
+    fi
+
     # -------------------------------------------------------------------------
     TEST "-fcallgraph-info"
 
@@ -844,6 +932,87 @@ EOF
         expect_contains output.ltrans0.ltrans.ci code.c
     fi
 
+    # -------------------------------------------------------------------------
+    TEST "-fcallgraph-info with -flto -fno-lto"
+
+    cat <<EOF >main.c
+extern int test();
+int main() { return test(); }
+EOF
+
+    cat <<EOF >code.c
+int test() { return 0; }
+EOF
+
+    if $COMPILER -c -fcallgraph-info -flto -fno-lto main.c >/dev/null 2>&1; then
+        $CCACHE_COMPILE -c -fcallgraph-info -flto -fno-lto main.c
+        $CCACHE_COMPILE -c -fcallgraph-info -flto -fno-lto code.c
+        $CCACHE_COMPILE -o output -fcallgraph-info -flto -fno-lto main.o code.o
+        expect_stat called_for_link 1
+        expect_stat direct_cache_hit 0
+        expect_stat preprocessed_cache_hit 0
+        expect_stat cache_miss 2
+        expect_exists main.ci
+        expect_exists code.ci
+        expect_missing output.ltrans0.ltrans.ci
+
+        rm main.ci
+        rm code.ci
+
+        $CCACHE_COMPILE -c -fcallgraph-info -flto -fno-lto main.c
+        $CCACHE_COMPILE -c -fcallgraph-info -flto -fno-lto code.c
+        $CCACHE_COMPILE -o output -fcallgraph-info -flto -fno-lto main.o code.o
+        expect_stat called_for_link 2
+        expect_stat direct_cache_hit 2
+        expect_stat preprocessed_cache_hit 0
+        expect_stat cache_miss 2
+        expect_exists main.ci
+        expect_exists code.ci
+        expect_missing output.ltrans0.ltrans.ci
+    fi
+
+    # -------------------------------------------------------------------------
+    TEST "-fcallgraph-info with -fno-lto -flto"
+
+    cat <<EOF >main.c
+extern int test();
+int main() { return test(); }
+EOF
+
+    cat <<EOF >code.c
+int test() { return 0; }
+EOF
+
+    if $COMPILER -c -fcallgraph-info -fno-lto -flto main.c >/dev/null 2>&1; then
+        $CCACHE_COMPILE -c -fcallgraph-info -fno-lto -flto main.c
+        $CCACHE_COMPILE -c -fcallgraph-info -fno-lto -flto code.c
+        $CCACHE_COMPILE -o output -fcallgraph-info -fno-lto -flto main.o code.o
+        expect_stat called_for_link 1
+        expect_stat direct_cache_hit 0
+        expect_stat preprocessed_cache_hit 0
+        expect_stat cache_miss 2
+        expect_missing main.ci
+        expect_missing code.ci
+        expect_exists output.ltrans0.ltrans.ci
+        expect_contains output.ltrans0.ltrans.ci main.c
+        expect_contains output.ltrans0.ltrans.ci code.c
+
+        rm output.ltrans0.ltrans.ci
+
+        $CCACHE_COMPILE -c -fcallgraph-info -fno-lto -flto main.c
+        $CCACHE_COMPILE -c -fcallgraph-info -fno-lto -flto code.c
+        $CCACHE_COMPILE -o output -fcallgraph-info -fno-lto -flto main.o code.o
+        expect_stat called_for_link 2
+        expect_stat direct_cache_hit 2
+        expect_stat preprocessed_cache_hit 0
+        expect_stat cache_miss 2
+        expect_missing main.ci
+        expect_missing code.ci
+        expect_exists output.ltrans0.ltrans.ci
+        expect_contains output.ltrans0.ltrans.ci main.c
+        expect_contains output.ltrans0.ltrans.ci code.c
+    fi
+
     # -------------------------------------------------------------------------
     TEST "Direct mode on cache created by ccache without direct mode support"