[clang] [Lexer] Prevent hitting the file system for ASTReader tokens (PR #192492)

via cfe-commits cfe-commits at lists.llvm.org
Sun Apr 19 09:52:45 PDT 2026


https://github.com/lucasvallejoo updated https://github.com/llvm/llvm-project/pull/192492

>From 35fb3a276bcb6b701dd56539cf3a4265bda4ae85 Mon Sep 17 00:00:00 2001
From: lucasvallejoo <lucas.valfac at gmail.com>
Date: Thu, 16 Apr 2026 19:20:48 +0200
Subject: [PATCH] [Lexer] Prevent hitting the file system for ASTReader tokens

This patch resolves an issue where the Lexer would attempt to measure
token lengths from the physical file system (via MeasureTokenLength)
even when the SourceLocation was already loaded from a precompiled
AST or module.

In environments like interactive C++ (ROOT/Cling) where the original
headers might be temporary or removed after the PCH generation, this
caused fatal 'file not found' errors.

This upstreaming effort matches ROOT-7111. It includes a robust,
cross-platform regression test that deletes the underlying header and
uses -ast-dump to force source location resolution without triggering
the diagnostics engine's file system checks.
---
 clang/lib/Lex/Lexer.cpp                 |  4 ++++
 clang/test/Lexer/pch-deleted-header.cpp | 15 +++++++++++++++
 2 files changed, 19 insertions(+)
 create mode 100644 clang/test/Lexer/pch-deleted-header.cpp

diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index 10246552bb13d..39686caa1879d 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -874,6 +874,10 @@ SourceLocation Lexer::getLocForEndOfToken(SourceLocation Loc, unsigned Offset,
       return Loc;
   }
 
+  // Don't hit the file system for ASTReader tokens.
+  if (SM.isLoadedSourceLocation(Loc))
+    return Loc;
+
   unsigned Len = Lexer::MeasureTokenLength(Loc, SM, LangOpts);
   if (Len > Offset)
     Len = Len - Offset;
diff --git a/clang/test/Lexer/pch-deleted-header.cpp b/clang/test/Lexer/pch-deleted-header.cpp
new file mode 100644
index 0000000000000..31b7ed330fd9f
--- /dev/null
+++ b/clang/test/Lexer/pch-deleted-header.cpp
@@ -0,0 +1,15 @@
+// RUN: rm -f %t.h %t.pch
+// RUN: echo "int variable_del_cern = 42;" > %t.h
+// RUN: %clang_cc1 -x c++-header -emit-pch -o %t.pch %t.h
+// RUN: rm %t.h
+// RUN: %clang_cc1 -fno-validate-pch -ast-dump -include-pch %t.pch %s
+
+// This test ensures that Clang does not access the filesystem when
+// handling SourceLocations originating from a PCH.
+//
+// After generating the PCH, the original header is removed. If Clang
+// attempts to access it (e.g. via MeasureTokenLength), the test will fail.
+
+int function() { 
+    return variable_del_cern; 
+}



More information about the cfe-commits mailing list