Skip to content

Commit 5e0487a

Browse files
[CIR] Fix parsing of #cir.unwind and cir.resume for catch regions (#1859)
1. **Catch Entry Parsing**: `parseCatchEntry` in `CIRDialect.cpp` now properly handles `#cir.unwind` attributes 2. **Resume Operation**: Fix record definition of `cir.resume` in order to handle locations correctly ## Issue: - `error: expected '{' to begin a region` when parsing `catch [#cir.unwind {` - `error: undefined symbol alias id` when parsing `cir.resume loc(#loc)`
1 parent 1bd9d47 commit 5e0487a

File tree

3 files changed

+78
-16
lines changed

3 files changed

+78
-16
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,9 +1095,8 @@ def CIR_ResumeOp : CIR_Op<"resume", [
10951095
Optional<CIR_UInt32>:$type_id,
10961096
UnitAttr:$rethrow);
10971097
let assemblyFormat = [{
1098-
($rethrow^)?
1099-
($exception_ptr^)?
1100-
(`,` $type_id^)?
1098+
(`rethrow` $rethrow^)?
1099+
($exception_ptr^ (`,` $type_id^)?)?
11011100
attr-dict
11021101
}];
11031102
}

clang/lib/CIR/Dialect/IR/CIRDialect.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1709,23 +1709,24 @@ ParseResult parseCatchRegions(
17091709
};
17101710

17111711
auto parseCatchEntry = [&]() -> ParseResult {
1712-
mlir::Type exceptionType;
17131712
mlir::Attribute exceptionTypeInfo;
17141713

1715-
// FIXME: support most recent syntax, currently broken.
1716-
::llvm::StringRef attrStr;
1717-
if (!parser.parseOptionalKeyword(&attrStr, {"all"})) {
1718-
if (parser.parseKeyword("type").failed())
1719-
return parser.emitError(parser.getCurrentLocation(),
1720-
"expected 'type' keyword here");
1721-
if (parser.parseType(exceptionType).failed())
1722-
return parser.emitError(parser.getCurrentLocation(),
1723-
"expected valid exception type");
1724-
if (parser.parseAttribute(exceptionTypeInfo).failed())
1714+
if (parser.parseOptionalAttribute(exceptionTypeInfo).has_value()) {
1715+
catchList.push_back(exceptionTypeInfo);
1716+
} else {
1717+
::llvm::StringRef attrStr;
1718+
if (parser.parseOptionalKeyword(&attrStr, {"all"}).succeeded()) {
1719+
// "all" keyword found, exceptionTypeInfo remains null
1720+
} else if (parser.parseOptionalKeyword("type").succeeded()) {
1721+
if (parser.parseAttribute(exceptionTypeInfo).failed())
1722+
return parser.emitError(parser.getCurrentLocation(),
1723+
"expected valid RTTI info attribute");
1724+
} else {
17251725
return parser.emitError(parser.getCurrentLocation(),
1726-
"expected valid RTTI info attribute");
1726+
"expected attribute, 'all', or 'type' keyword");
1727+
}
1728+
catchList.push_back(exceptionTypeInfo);
17271729
}
1728-
catchList.push_back(exceptionTypeInfo);
17291730
return parseAndCheckRegion();
17301731
};
17311732

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// RUN: cir-opt %s | FileCheck %s
2+
3+
// Test ClangIR exception handling parsing fix
4+
// This demonstrates the syntax that was failing before the fix:
5+
// 1. #cir.unwind attributes in catch blocks
6+
// 2. cir.resume operations with location information
7+
8+
!void = !cir.void
9+
10+
#loc1 = loc("simple.cpp":10:5)
11+
#loc2 = loc("simple.cpp":15:8)
12+
13+
module {
14+
// This represents C++ code like:
15+
// void function() {
16+
// RAII_Object obj; // needs cleanup on exception
17+
// }
18+
19+
// CHECK-LABEL: @simple_cleanup_example
20+
cir.func @simple_cleanup_example() -> !void {
21+
cir.try {
22+
// Normal execution path
23+
cir.return
24+
} catch [#cir.unwind {
25+
// Cleanup/unwind region - not a real exception handler
26+
// Before the fix: "undefined symbol alias id 'loc1'"
27+
// CHECK: cir.resume
28+
cir.resume loc(#loc1)
29+
}]
30+
cir.return
31+
}
32+
33+
// This represents C++ code like:
34+
// void function() {
35+
// try { /* some code */ }
36+
// catch (...) { throw; } // rethrow
37+
// }
38+
39+
// CHECK-LABEL: @rethrow_example
40+
cir.func @rethrow_example() -> !void {
41+
cir.try {
42+
cir.return
43+
} catch [#cir.unwind {
44+
// Rethrow - continue unwinding to find real handler
45+
// CHECK: cir.resume rethrow
46+
cir.resume rethrow loc(#loc2)
47+
}]
48+
cir.return
49+
}
50+
51+
// CHECK-LABEL: @test_unwind_catch_parsing
52+
cir.func @test_unwind_catch_parsing() -> !void {
53+
cir.try {
54+
cir.return
55+
} catch [#cir.unwind {
56+
// CHECK: cir.resume
57+
cir.resume
58+
}]
59+
// CHECK: cir.return
60+
cir.return
61+
}
62+
}

0 commit comments

Comments
 (0)