[clang] [clang][Driver] - Set FinalPhase to Precompile for PCH (PR #213164)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 31 07:13:34 PDT 2026
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 <ethan.stewart at amd.com>
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
More information about the cfe-commits
mailing list