[clang] [clang] Skip host default include paths for GPU triples (PR #192821)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Apr 18 20:14:05 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Yaxun (Sam) Liu (yxsamliu)
<details>
<summary>Changes</summary>
GPU compiles are freestanding. They should not search the host system's
`/usr/include` or `/usr/local/include` by default.
A concrete example is
clang --target=amdgcn-amd-amdhsa -ffreestanding -nogpulib -c foo.c
If `foo.c` contains `#include <string.h>`, Clang should not read the host
header `/usr/include/string.h`. That header belongs to the host libc, not
to the GPU target. On current `main`, however, GPU triples still fall
through to the generic default-include logic, so host include paths are
added and builds can fail on host-only headers such as
`bits/libc-header-start.h`.
Fix this in two parts:
1. In `InitHeaderSearch`, treat all GPU triples (`triple.isGPU()`) like
other targets whose include paths are managed by the driver, and skip
the generic host default-include fallback.
2. In the AMDGPU and NVPTX toolchains, add clang's resource-directory
builtin headers explicitly (`stddef.h`, `float.h`, `stdint.h`, ...).
These are still needed, but they should come from clang's builtin
header directory, not from the host libc.
Add a lit test that checks the printed include search list for GPU
triples and verifies that `/usr/include` and `/usr/local/include` are
not present.
Related: PR #<!-- -->177665.
---
Full diff: https://github.com/llvm/llvm-project/pull/192821.diff
4 Files Affected:
- (modified) clang/lib/Driver/ToolChains/AMDGPU.cpp (+15-2)
- (modified) clang/lib/Driver/ToolChains/Cuda.cpp (+15-2)
- (modified) clang/lib/Lex/InitHeaderSearch.cpp (+10)
- (added) clang/test/Preprocessor/gpu-targets-no-host-default-includes.c (+19)
``````````diff
diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp
index ff4c781d51348..e229635745dc9 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp
@@ -879,8 +879,21 @@ void AMDGPUToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {
void AMDGPUToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
- if (DriverArgs.hasArg(options::OPT_nostdinc) ||
- DriverArgs.hasArg(options::OPT_nostdlibinc))
+ if (DriverArgs.hasArg(options::OPT_nostdinc))
+ return;
+
+ // Add clang's builtin headers (`stddef.h`, `float.h`, `stdint.h`, ...).
+ // These are compiler-provided headers, not host libc headers.
+ //
+ // Example: an amdgcn compile may still need `float.h`, but it should come
+ // from clang's resource directory, not from the host system's `/usr/include`.
+ if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
+ SmallString<128> ResourceDirInclude(getDriver().ResourceDir);
+ llvm::sys::path::append(ResourceDirInclude, "include");
+ addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude);
+ }
+
+ if (DriverArgs.hasArg(options::OPT_nostdlibinc))
return;
// Add multilib variant include paths in priority order.
diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp
index dcde82cdf4d85..7c248e3c433f9 100644
--- a/clang/lib/Driver/ToolChains/Cuda.cpp
+++ b/clang/lib/Driver/ToolChains/Cuda.cpp
@@ -790,8 +790,21 @@ void NVPTXToolChain::addClangTargetOptions(
void NVPTXToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
- if (DriverArgs.hasArg(options::OPT_nostdinc) ||
- DriverArgs.hasArg(options::OPT_nostdlibinc))
+ if (DriverArgs.hasArg(options::OPT_nostdinc))
+ return;
+
+ // Add clang's builtin headers (`stddef.h`, `float.h`, `stdint.h`, ...).
+ // These are compiler-provided headers, not host libc headers.
+ //
+ // Example: an nvptx compile may still need `float.h`, but it should come
+ // from clang's resource directory, not from the host system's `/usr/include`.
+ if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
+ SmallString<128> ResourceDirInclude(getDriver().ResourceDir);
+ llvm::sys::path::append(ResourceDirInclude, "include");
+ addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude);
+ }
+
+ if (DriverArgs.hasArg(options::OPT_nostdlibinc))
return;
// Add multilib variant include paths in priority order.
diff --git a/clang/lib/Lex/InitHeaderSearch.cpp b/clang/lib/Lex/InitHeaderSearch.cpp
index e894086b66e76..7204602dc5514 100644
--- a/clang/lib/Lex/InitHeaderSearch.cpp
+++ b/clang/lib/Lex/InitHeaderSearch.cpp
@@ -210,6 +210,16 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
bool InitHeaderSearch::ShouldAddDefaultIncludePaths(
const llvm::Triple &triple) {
+ // GPU targets are freestanding, so they should not search the host system's
+ // `/usr/include` or `/usr/local/include`.
+ //
+ // Example: `clang --target=amdgcn-amd-amdhsa -ffreestanding -nogpulib`
+ // compiling a file with `#include <string.h>` should not read the host
+ // glibc header `/usr/include/string.h`. GPU toolchains add their own include
+ // paths explicitly, so skip the generic host fallback here.
+ if (triple.isGPU())
+ return false;
+
switch (triple.getOS()) {
case llvm::Triple::AIX:
case llvm::Triple::DragonFly:
diff --git a/clang/test/Preprocessor/gpu-targets-no-host-default-includes.c b/clang/test/Preprocessor/gpu-targets-no-host-default-includes.c
new file mode 100644
index 0000000000000..952c4b98c0fe9
--- /dev/null
+++ b/clang/test/Preprocessor/gpu-targets-no-host-default-includes.c
@@ -0,0 +1,19 @@
+// Check that GPU targets do not get the host system's default C include
+// paths (e.g. /usr/include, /usr/local/include) appended to the search list.
+// GPU toolchains are freestanding and manage their own include paths.
+//
+// Use `-v -E` on the source with `-nogpulib` to print the toolchain's
+// include search list and verify the host paths are absent.
+
+// RUN: %clang --target=amdgcn-amd-amdhsa -nogpulib -v -E -x c %s \
+// RUN: -o /dev/null 2>&1 | FileCheck %s
+
+// RUN: %clang --target=amdgcn--amdhsa -nogpulib -v -E -x c %s \
+// RUN: -o /dev/null 2>&1 | FileCheck %s
+
+// RUN: %clang --target=nvptx64-nvidia-cuda -nogpulib -nogpuinc -v -E -x c %s \
+// RUN: -o /dev/null 2>&1 | FileCheck %s
+
+// CHECK-NOT: /usr/include{{$}}
+// CHECK-NOT: /usr/local/include{{$}}
+// CHECK: End of search list.
``````````
</details>
https://github.com/llvm/llvm-project/pull/192821
More information about the cfe-commits
mailing list