Skip to content

[mlir] Fix crash in diagnostic verifier for unmatched @unknown expectations#186148

Merged
joker-eph merged 1 commit into
llvm:mainfrom
joker-eph:fix/issue-163343
Mar 17, 2026
Merged

[mlir] Fix crash in diagnostic verifier for unmatched @unknown expectations#186148
joker-eph merged 1 commit into
llvm:mainfrom
joker-eph:fix/issue-163343

Conversation

@joker-eph

Copy link
Copy Markdown
Contributor

When an expected-* directive uses the @unknown location specifier, the associated ExpectedDiag record has an invalid (null) SMLoc as its fileLoc. If the expected diagnostic is never produced, emitError() is called to report the unmatched expectation, but it unconditionally constructs an SMRange from fileLoc, triggering a null-pointer dereference (UBSan) and an assertion failure in SMRange's constructor which requires both endpoints to have equal validity.

Fix by guarding the SMRange construction with a fileLoc.isValid() check. When fileLoc is invalid, call PrintMessage without a source range.

Fixes #163343

Assisted-by: Claude Code

…ations

When an expected-* directive uses the @unknown location specifier, the
associated ExpectedDiag record has an invalid (null) SMLoc as its fileLoc.
If the expected diagnostic is never produced, emitError() is called to
report the unmatched expectation, but it unconditionally constructs an
SMRange from fileLoc, triggering a null-pointer dereference (UBSan) and
an assertion failure in SMRange's constructor which requires both endpoints
to have equal validity.

Fix by guarding the SMRange construction with a fileLoc.isValid() check.
When fileLoc is invalid, call PrintMessage without a source range.

Fixes llvm#163343
@llvmbot llvmbot added mlir:core MLIR Core Infrastructure mlir labels Mar 12, 2026
@llvmbot

llvmbot commented Mar 12, 2026

Copy link
Copy Markdown
Member

@llvm/pr-subscribers-mlir

@llvm/pr-subscribers-mlir-core

Author: Mehdi Amini (joker-eph)

Changes

When an expected-* directive uses the @unknown location specifier, the associated ExpectedDiag record has an invalid (null) SMLoc as its fileLoc. If the expected diagnostic is never produced, emitError() is called to report the unmatched expectation, but it unconditionally constructs an SMRange from fileLoc, triggering a null-pointer dereference (UBSan) and an assertion failure in SMRange's constructor which requires both endpoints to have equal validity.

Fix by guarding the SMRange construction with a fileLoc.isValid() check. When fileLoc is invalid, call PrintMessage without a source range.

Fixes #163343

Assisted-by: Claude Code


Full diff: https://github.com/llvm/llvm-project/pull/186148.diff

2 Files Affected:

  • (modified) mlir/lib/IR/Diagnostics.cpp (+11-3)
  • (added) mlir/test/mlir-opt/expected-unknown-loc-unmatched.mlir (+9)
diff --git a/mlir/lib/IR/Diagnostics.cpp b/mlir/lib/IR/Diagnostics.cpp
index f4c9242ed3479..5caf826c84bdd 100644
--- a/mlir/lib/IR/Diagnostics.cpp
+++ b/mlir/lib/IR/Diagnostics.cpp
@@ -600,9 +600,17 @@ struct ExpectedDiag {
   /// Emit an error at the location referenced by this diagnostic.
   LogicalResult emitError(raw_ostream &os, llvm::SourceMgr &mgr,
                           const Twine &msg) {
-    SMRange range(fileLoc, SMLoc::getFromPointer(fileLoc.getPointer() +
-                                                 substring.size()));
-    mgr.PrintMessage(os, fileLoc, llvm::SourceMgr::DK_Error, msg, range);
+    // fileLoc may be invalid when the expected diagnostic used an unknown
+    // location specifier (e.g. `// expected-error @unknown {{...}}`). In that
+    // case, skip the source range to avoid a null-pointer dereference and an
+    // assertion in SMRange that both endpoints must have the same validity.
+    if (fileLoc.isValid()) {
+      SMRange range(fileLoc, SMLoc::getFromPointer(fileLoc.getPointer() +
+                                                   substring.size()));
+      mgr.PrintMessage(os, fileLoc, llvm::SourceMgr::DK_Error, msg, range);
+    } else {
+      mgr.PrintMessage(os, fileLoc, llvm::SourceMgr::DK_Error, msg);
+    }
     return failure();
   }
 
diff --git a/mlir/test/mlir-opt/expected-unknown-loc-unmatched.mlir b/mlir/test/mlir-opt/expected-unknown-loc-unmatched.mlir
new file mode 100644
index 0000000000000..5a06d386dabf8
--- /dev/null
+++ b/mlir/test/mlir-opt/expected-unknown-loc-unmatched.mlir
@@ -0,0 +1,9 @@
+// Test that an unmatched `expected-*` directive using the `@unknown` location
+// specifier emits a diagnostic instead of crashing.
+// See https://github.com/llvm/llvm-project/issues/163343
+
+// RUN: not mlir-opt --verify-diagnostics %s 2>&1 | FileCheck %s
+
+// CHECK: expected warning "some warning that is never produced" was not produced
+
+// expected-warning @unknown {{some warning that is never produced}}

@joker-eph

Copy link
Copy Markdown
Contributor Author

Ping on this @matthias-springer @jpienaar ?

@joker-eph joker-eph merged commit 055322c into llvm:main Mar 17, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mlir:core MLIR Core Infrastructure mlir

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[mlir] null pointer UBSan alert in mlir/lib/IR/Diagnostics.cpp

3 participants