[Mlir-commits] [mlir] aa4c76d - [mlir][BytecodeReader] Fix crash reading FusedLoc with empty locations (#189228)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Tue Apr 7 03:51:59 PDT 2026
Author: Mehdi Amini
Date: 2026-04-07T12:51:54+02:00
New Revision: aa4c76d8fb2211cf911a73533138baa24f23b34d
URL: https://github.com/llvm/llvm-project/commit/aa4c76d8fb2211cf911a73533138baa24f23b34d
DIFF: https://github.com/llvm/llvm-project/commit/aa4c76d8fb2211cf911a73533138baa24f23b34d.diff
LOG: [mlir][BytecodeReader] Fix crash reading FusedLoc with empty locations (#189228)
FusedLoc::get(context, locs) may return UnknownLoc when locs is empty
and no metadata is provided. The bytecode reader's cBuilder used
cast<FusedLoc>() on this result, which crashes with an assertion
failure.
Fix by giving the FusedLoc DialectAttribute its own cBuilder that passes
Attribute() explicitly, causing getChecked<FusedLoc> to call the
two-parameter storage constructor directly and always produce a
FusedLoc.
Fixes #99626
Assisted-by: Claude Code
Added:
Modified:
mlir/include/mlir/IR/BuiltinDialectBytecode.td
mlir/unittests/Bytecode/BytecodeTest.cpp
Removed:
################################################################################
diff --git a/mlir/include/mlir/IR/BuiltinDialectBytecode.td b/mlir/include/mlir/IR/BuiltinDialectBytecode.td
index 8a1f3d5e5b2e0..c97d093c84e51 100644
--- a/mlir/include/mlir/IR/BuiltinDialectBytecode.td
+++ b/mlir/include/mlir/IR/BuiltinDialectBytecode.td
@@ -116,12 +116,15 @@ def FileLineColLoc : DialectAttribute<(attr
}
}
-let cType = "FusedLoc",
- cBuilder = "cast<FusedLoc>(getChecked<FusedLoc>([&]() { return reader.emitError(); }, context, $_args))" in {
+let cType = "FusedLoc" in {
def FusedLoc : DialectAttribute<(attr
Array<Location>:$locations
)> {
let printerPredicate = "!$_val.getMetadata()";
+ // FusedLoc::get(context, locs) may return UnknownLoc when locs is empty.
+ // Pass Attribute() explicitly to bypass the folding logic and always
+ // construct a FusedLoc via Base::getChecked.
+ let cBuilder = "cast<FusedLoc>(getChecked<FusedLoc>([&]() { return reader.emitError(); }, context, $_args, Attribute()))";
}
def FusedLocWithMetadata : DialectAttribute<(attr
@@ -129,6 +132,7 @@ def FusedLocWithMetadata : DialectAttribute<(attr
Attribute:$metadata
)> {
let printerPredicate = "$_val.getMetadata()";
+ let cBuilder = "cast<FusedLoc>(getChecked<FusedLoc>([&]() { return reader.emitError(); }, context, $_args))";
}
}
diff --git a/mlir/unittests/Bytecode/BytecodeTest.cpp b/mlir/unittests/Bytecode/BytecodeTest.cpp
index 148868801da33..51eebc488d7f8 100644
--- a/mlir/unittests/Bytecode/BytecodeTest.cpp
+++ b/mlir/unittests/Bytecode/BytecodeTest.cpp
@@ -266,3 +266,29 @@ TEST(Bytecode, DeepCallSiteLoc) {
// Verify the location matches.
EXPECT_EQ(module.get()->getLoc(), roundTripped->getLoc());
}
+
+// Regression test for https://github.com/llvm/llvm-project/issues/99626.
+// FusedLoc::get(context, locs) returns UnknownLoc when locs is empty, so the
+// bytecode reader must not use cast<FusedLoc>() on that result.
+TEST(Bytecode, EmptyFusedLocRoundtrip) {
+ MLIRContext context;
+
+ // FusedLoc with empty locations (no metadata). FusedLoc::get returns
+ // UnknownLoc in this case, but the bytecode writer stores a FusedLoc.
+ FusedLoc fusedLoc = FusedLoc::get(&context, /*locs=*/{}, /*metadata=*/{});
+ auto module = mlir::ModuleOp::create(fusedLoc, "test");
+
+ // Write the module to bytecode.
+ std::string buffer;
+ llvm::raw_string_ostream ostream(buffer);
+ ASSERT_TRUE(succeeded(writeBytecodeToFile(module, ostream)));
+ ostream.flush();
+
+ // Parse it back - this used to crash with an assertion failure in cast<>.
+ ParserConfig parseConfig(&context);
+ OwningOpRef<Operation *> roundTripModule =
+ parseSourceString<Operation *>(buffer, parseConfig);
+ ASSERT_TRUE(roundTripModule);
+
+ module.erase();
+}
More information about the Mlir-commits
mailing list