https://github.com/jansvoboda11 created 
https://github.com/llvm/llvm-project/pull/215962

The `-Wshadow-header` warning introduced in 
https://github.com/llvm/llvm-project/pull/162491 gets enabled by `-Weverything` 
and causes O(N*M) extra `status()` syscalls (where N is the number of includes, 
M is the number of search paths). This is caused by proactively probing search 
paths even after finding a suitable header, and calling `FileManager` with 
`CacheFailure = false`.

There's no reason to not cache the non-existence of header files during these 
probes. This PR starts caching these and adds a regression test.

>From d1d026afc0f0c7fe642742edc3c5e0d9e800dd31 Mon Sep 17 00:00:00 2001
From: Jan Svoboda <[email protected]>
Date: Thu, 13 Aug 2026 08:19:00 +0200
Subject: [PATCH] [clang] Cache stat failures in `-Wshadow-header`

The `-Wshadow-header` warning introduced in 
https://github.com/llvm/llvm-project/pull/162491 gets enabled by `-Weverything` 
and causes O(N*M) extra `status()` syscalls (where N is the number of includes, 
M is the number of search paths). This is caused by proactively probing search 
paths even after finding a suitable header, and calling `FileManager` with 
`CacheFailure = false`.

There's no reason to not cache the non-existence of header files during these 
probes. This PR starts caching these and adds a regression test.
---
 clang/lib/Lex/HeaderSearch.cpp                |  4 ++--
 .../Preprocessor/header-shadowing-stats.c     | 22 +++++++++++++++++++
 2 files changed, 24 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/Preprocessor/header-shadowing-stats.c

diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
index ecd80db10f2bd..911997a10eba5 100644
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ b/clang/lib/Lex/HeaderSearch.cpp
@@ -907,7 +907,7 @@ void HeaderSearch::diagnoseHeaderShadowing(
       const auto &IncluderAndDir = Includers[i];
       SmallString<1024> TmpDir = IncluderAndDir.second.getName();
       llvm::sys::path::append(TmpDir, Filename);
-      if (auto File = getFileMgr().getOptionalFileRef(TmpDir, false, false)) {
+      if (auto File = getFileMgr().getOptionalFileRef(TmpDir)) {
         if (&File->getFileEntry() == *FE)
           continue;
         Diags.Report(IncludeLoc, diag::warn_header_shadowing)
@@ -932,7 +932,7 @@ void HeaderSearch::diagnoseHeaderShadowing(
       continue;
     SmallString<1024> TmpPath = It->getName();
     llvm::sys::path::append(TmpPath, Filename);
-    if (auto File = getFileMgr().getOptionalFileRef(TmpPath, false, false)) {
+    if (auto File = getFileMgr().getOptionalFileRef(TmpPath)) {
       if (&File->getFileEntry() == *FE)
         continue;
       Diags.Report(IncludeLoc, diag::warn_header_shadowing)
diff --git a/clang/test/Preprocessor/header-shadowing-stats.c 
b/clang/test/Preprocessor/header-shadowing-stats.c
new file mode 100644
index 0000000000000..2408305492824
--- /dev/null
+++ b/clang/test/Preprocessor/header-shadowing-stats.c
@@ -0,0 +1,22 @@
+// This test checks that -Wshadow-header doesn't repeatedly perform the same 
IO.
+
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+
+//--- tu1.c
+#include "header.h"
+//--- tu2.c
+#include "header.h"
+// The following line should not trigger more IO:
+#include "header.h"
+//--- include1/header.h
+//--- include2/keep.h
+
+// RUN: %clang_cc1 -Eonly %t/tu1.c -I %t/include1 -I %t/include2 
-Wshadow-header -print-stats 2>%t/tu1.stats
+// RUN: %clang_cc1 -Eonly %t/tu2.c -I %t/include1 -I %t/include2 
-Wshadow-header -print-stats 2>%t/tu2.stats
+
+// RUN: cat %t/tu1.stats %t/tu2.stats | FileCheck %s
+// CHECK:      *** Virtual File System Stats:
+// CHECK-NEXT: [[STATUS_COUNT:[0-9]+]] status() calls
+// CHECK:      *** Virtual File System Stats:
+// CHECK-NEXT: [[STATUS_COUNT]] status() calls

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to