https://github.com/estewart08 updated https://github.com/llvm/llvm-project/pull/213164
>From 54b8a2a7df65d27415aa4125e2d93d13069c2df0 Mon Sep 17 00:00:00 2001 From: Ethan Stewart <[email protected]> Date: Mon, 27 Jul 2026 15:24:46 -0500 Subject: [PATCH] [clang][Driver] - Set FinalPhase to Precompile for PCH Currently, a PCH compilation without --precompile, -c, or -S will have a link FinalPhase. If there happens to be a linker flag present on a precompiled header compilation then clang will output an error: clang -x c++-header test.h -lm -o test.h.pch clang: error: cannot specify -o when generating multiple output files The Driver should be smart enough to ignore the flags. This is done by checking for TY_PCH and setting the FinalPhase to phases::Precompile. This was originaly noticed when a clang config file had some linker flags. I have included that case in the lit test as well. Assisted-by: AI for initial diagnosis/recommendations (Claude Opus 4.8) --- clang/lib/Driver/Driver.cpp | 15 ++++++++++++++- clang/test/Driver/pch-ignore-linker-flags.cpp | 13 +++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 clang/test/Driver/pch-ignore-linker-flags.cpp diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 38795f7c2ae7a..ca1c9bef997c6 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -358,6 +358,11 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, Arg *PhaseArg = nullptr; phases::ID FinalPhase; + // Collect -x for PCH check below + Arg *XArg = DAL.getLastArg(options::OPT_x); + types::ID XTy = XArg ? types::lookupTypeForTypeSpecifier(XArg->getValue()) + : types::TY_INVALID; + // -{E,EP,P,M,MM} only run the preprocessor. if (CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) || (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) || @@ -376,6 +381,7 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header, options::OPT_fmodule_header_EQ))) { FinalPhase = phases::Precompile; + // -{fsyntax-only,-analyze,emit-ast} only run up to the compiler. } else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) || (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) || @@ -401,7 +407,14 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, } else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) { FinalPhase = phases::IfsMerge; - // Otherwise do everything. + // PCH compilation (with no -c/-S/--precompile) should not have a + // link final phase + } else if (XArg && XTy != types::TY_INVALID && + types::getPrecompiledType(XTy) == types::TY_PCH) { + PhaseArg = XArg; + FinalPhase = phases::Precompile; + + // Otherwise do everything. } else FinalPhase = phases::Link; diff --git a/clang/test/Driver/pch-ignore-linker-flags.cpp b/clang/test/Driver/pch-ignore-linker-flags.cpp new file mode 100644 index 0000000000000..4964e2239aa38 --- /dev/null +++ b/clang/test/Driver/pch-ignore-linker-flags.cpp @@ -0,0 +1,13 @@ +// // RUN: rm -rf %t +// // RUN: mkdir -p %t +// +// // Create PCH and ignore linker flags. +// // RUN: %clang -x c++-header %S/Inputs/pchfile.h -lm -o %t/pchfile.h.pch -### 2>&1 | FileCheck %s -check-prefix=CHECK-IGNORE-LINK-FLAGS,CHECK-EMIT-PCH +// // RUN: %clang -x c++-header %S/Inputs/pchfile.h -lm -### 2>&1 | FileCheck %s -check-prefix=CHECK-IGNORE-LINK-FLAGS,CHECK-EMIT-PCH +// // RUN: %clang --config %S/Inputs/config-l.cfg -x c++-header %S/Inputs/pchfile.h -o %t/pchfile.h.pch -### 2>&1 | FileCheck %s -check-prefix=CHECK-IGNORE-LINK-FLAGS-CFG,CHECK-EMIT-PCH +// +// // CHECK-IGNORE-LINK-FLAGS: warning: -lm: 'linker' input unused +// // CHECK-IGNORE-LINK-FLAGS-NOT: clang: error: cannot specify -o when generating multiple output files +// // CHECK-EMIT-PCH: -emit-pch +// // CHECK-IGNORE-LINK-FLAGS-CFG: -Wall +// // CHECK-IGNORE-LINK-FLAGS-CFG-NOT: -lm --as-needed -Bstatic -lhappy -Bdynamic _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
