[llvm-branch-commits] [llvm] [Support] Track verify directives per buffer instead of per file name (PR #233306)

Alexander Richardson via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Oct 20 14:56:55 PDT 2026


https://github.com/arichardson updated https://github.com/llvm/llvm-project/pull/233306

>From 3c72dd71cd4723b752202e6779952a3170461f75 Mon Sep 17 00:00:00 2001
From: Alex Richardson <alexrichardson at google.com>
Date: Tue, 20 Oct 2026 14:56:16 -0700
Subject: [PATCH] [nspr] initial commit

---
 .../Support/SourceMgrDiagnosticVerifier.h     | 12 +++++-----
 .../Support/SourceMgrDiagnosticVerifier.cpp   | 24 ++++++++++---------
 .../SourceMgrDiagnosticVerifierTest.cpp       | 17 +++++++++++++
 3 files changed, 36 insertions(+), 17 deletions(-)

diff --git a/llvm/include/llvm/Support/SourceMgrDiagnosticVerifier.h b/llvm/include/llvm/Support/SourceMgrDiagnosticVerifier.h
index 574e717814098..cc1060ab3ccb1 100644
--- a/llvm/include/llvm/Support/SourceMgrDiagnosticVerifier.h
+++ b/llvm/include/llvm/Support/SourceMgrDiagnosticVerifier.h
@@ -17,8 +17,8 @@
 #define LLVM_SUPPORT_SOURCEMGRDIAGNOSTICVERIFIER_H
 
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Regex.h"
 #include "llvm/Support/SourceMgr.h"
@@ -140,8 +140,8 @@ class LLVM_ABI SourceMgrDiagnosticVerifier {
   /// false and prints a message on error.
   bool computeRegex(ExpectedDiag &diag);
 
-  /// Scans \p buf for expected diagnostics and returns the list for its
-  /// buffer identifier.
+  /// Scans \p buf for expected diagnostics, if it has not been scanned yet,
+  /// and returns its list.
   MutableArrayRef<ExpectedDiag> computeExpectedDiags(const MemoryBuffer *buf);
 
   const SourceMgr &mgr;
@@ -156,9 +156,9 @@ class LLVM_ABI SourceMgrDiagnosticVerifier {
   /// Whether a directive can only match one diagnostic, see the constructor.
   bool oneDiagPerDirective;
 
-  /// The expected diagnostics for each buffer that has been scanned so far,
-  /// keyed by buffer identifier (i.e. file name).
-  StringMap<SmallVector<ExpectedDiag, 2>> expectedDiagsPerFile;
+  /// The expected diagnostics for each buffer that has been scanned so far.
+  DenseMap<const MemoryBuffer *, SmallVector<ExpectedDiag, 2>>
+      expectedDiagsPerBuffer;
 
   /// The expected diagnostics with an '@unknown' location.
   SmallVector<ExpectedDiag, 2> expectedUnknownLocDiags;
diff --git a/llvm/lib/Support/SourceMgrDiagnosticVerifier.cpp b/llvm/lib/Support/SourceMgrDiagnosticVerifier.cpp
index cd8b4c4c04730..246813d987180 100644
--- a/llvm/lib/Support/SourceMgrDiagnosticVerifier.cpp
+++ b/llvm/lib/Support/SourceMgrDiagnosticVerifier.cpp
@@ -121,7 +121,10 @@ SourceMgrDiagnosticVerifier::computeExpectedDiags(const MemoryBuffer *buf) {
   // If the buffer is invalid, return an empty list.
   if (!buf)
     return {};
-  auto &expectedDiags = expectedDiagsPerFile[buf->getBufferIdentifier()];
+  auto [It, Inserted] = expectedDiagsPerBuffer.try_emplace(buf);
+  if (!Inserted)
+    return It->second;
+  auto &expectedDiags = It->second;
 
   // The number of the last line that did not correlate to a designator.
   unsigned lastNonDesignatorLine = 0;
@@ -249,13 +252,7 @@ SourceMgrDiagnosticVerifier::process(SourceMgr::DiagKind kind,
   if (loc) {
     // If the buffer couldn't be resolved, `diags` stays empty: a diagnostic
     // with a location in an unknown file can never match anything.
-    if (loc->buf) {
-      auto it = expectedDiagsPerFile.find(loc->buf->getBufferIdentifier());
-      if (it != expectedDiagsPerFile.end())
-        diags = it->second;
-      else
-        diags = computeExpectedDiags(loc->buf);
-    }
+    diags = computeExpectedDiags(loc->buf);
   } else {
     diags = expectedUnknownLocDiags;
   }
@@ -330,11 +327,16 @@ bool SourceMgrDiagnosticVerifier::verify() {
       emitError(diag, "expected " + getDiagKindStr(diag.kind) + " \"" +
                           diag.substring + "\" was not produced");
   };
-  for (auto &expectedDiagsPair : expectedDiagsPerFile)
-    for (const ExpectedDiag &diag : expectedDiagsPair.second)
+  // Check buffers in registration order so that the output is deterministic.
+  for (unsigned i = 0, e = mgr.getNumBuffers(); i != e; ++i) {
+    auto it = expectedDiagsPerBuffer.find(mgr.getMemoryBuffer(i + 1));
+    if (it == expectedDiagsPerBuffer.end())
+      continue;
+    for (const ExpectedDiag &diag : it->second)
       checkExpectedDiags(diag);
+  }
   for (const ExpectedDiag &diag : expectedUnknownLocDiags)
     checkExpectedDiags(diag);
-  expectedDiagsPerFile.clear();
+  expectedDiagsPerBuffer.clear();
   return ok;
 }
diff --git a/llvm/unittests/Support/SourceMgrDiagnosticVerifierTest.cpp b/llvm/unittests/Support/SourceMgrDiagnosticVerifierTest.cpp
index 853d2394cafe6..050e1d494bffa 100644
--- a/llvm/unittests/Support/SourceMgrDiagnosticVerifierTest.cpp
+++ b/llvm/unittests/Support/SourceMgrDiagnosticVerifierTest.cpp
@@ -224,3 +224,20 @@ TEST_F(SourceMgrDiagnosticVerifierTest, OutOfBoundsLineOffsets) {
   EXPECT_NE(StringRef(Output).find("error: invalid line offset '+99999999999'"),
             StringRef::npos);
 }
+
+TEST_F(SourceMgrDiagnosticVerifierTest, BuffersWithSameName) {
+  const MemoryBuffer *Buf1 =
+      addBuffer("op\n# expected-error at -1 {{first}}\n", "same.s");
+  const MemoryBuffer *Buf2 =
+      addBuffer("op\n# expected-error at -1 {{second}}\n", "same.s");
+  SourceMgrDiagnosticVerifier Verifier(SM, OS);
+
+  // Directives only match diagnostics in their own buffer.
+  EXPECT_EQ(Verifier.process(getMessage(Buf2, SourceMgr::DK_Error, "first")),
+            MatchResult::Unexpected);
+  EXPECT_EQ(Verifier.process(getMessage(Buf1, SourceMgr::DK_Error, "first")),
+            MatchResult::Matched);
+  EXPECT_EQ(Verifier.process(getMessage(Buf2, SourceMgr::DK_Error, "second")),
+            MatchResult::Matched);
+  EXPECT_FALSE(Verifier.verify());
+}



More information about the llvm-branch-commits mailing list