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
