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}}