[clang] [CIR][EH] Preserved exception pointer address spaces in throw calls (PR #227595)

Kunal Dubey via cfe-commits cfe-commits at lists.llvm.org
Sat Oct 3 09:33:08 PDT 2026


================
@@ -4676,17 +4678,68 @@ ParseResult cir::InlineAsmOp::parse(OpAsmParser &parser,
 // ThrowOp / TryThrowOp
 //===----------------------------------------------------------------------===//
 
+using ThrowAddressSpaces = std::array<mlir::ptr::MemorySpaceAttrInterface, 3>;
+
+template <typename ThrowOpTy>
+static std::optional<ThrowAddressSpaces> getThrowAddressSpaces(ThrowOpTy op) {
+  if (!op.getExceptionPtr() || !op.getTypeInfo() || !op.getDtor())
+    return std::nullopt;
+
+  return ThrowAddressSpaces{
+      mlir::cast<cir::PointerType>(op.getExceptionPtr().getType())
+          .getAddrSpace(),
+      mlir::cast<cir::PointerType>(op.getTypeInfo().getType()).getAddrSpace(),
+      mlir::cast<cir::PointerType>(op.getDtor().getType()).getAddrSpace()};
+}
+
+static std::optional<ThrowAddressSpaces>
+getThrowAddressSpaces(mlir::Operation *op) {
+  if (auto throwOp = mlir::dyn_cast<cir::ThrowOp>(op))
+    return getThrowAddressSpaces(throwOp);
+  if (auto tryThrowOp = mlir::dyn_cast<cir::TryThrowOp>(op))
+    return getThrowAddressSpaces(tryThrowOp);
+  return std::nullopt;
+}
+
 template <typename ThrowOpTy>
 static mlir::LogicalResult verifyThrowOpImpl(ThrowOpTy op) {
-  if (op.rethrows())
+  bool hasExceptionPtr = static_cast<bool>(op.getExceptionPtr());
+  bool hasTypeInfo = static_cast<bool>(op.getTypeInfo());
+  bool hasDtor = static_cast<bool>(op.getDtor());
+
+  if (!hasExceptionPtr && !hasTypeInfo && !hasDtor)
     return mlir::success();
 
-  if (op.getNumOperands() != 0) {
-    if (op.getTypeInfo())
-      return mlir::success();
-    return op.emitOpError() << "'type_info' symbol attribute missing";
-  }
+  if (!hasExceptionPtr || !hasTypeInfo || !hasDtor)
+    return op.emitOpError()
+           << "must have either no operands for a rethrow or exception, "
+              "type_info, and destructor pointer operands for a throw";
+
+  auto module = op->template getParentOfType<mlir::ModuleOp>();
+  if (!module)
+    return op.emitOpError("expects an enclosing module");
+
+  mlir::Operation *firstThrow = nullptr;
+  std::optional<ThrowAddressSpaces> expectedAddressSpaces;
+  module.walk([&](mlir::Operation *candidate) {
----------------
xakep8 wrote:

That makes sense. I updated each throw to verify its own operands using the module’s data layout, and EHABILowering now uses the same layout when declaring __cxa_throw.

https://github.com/llvm/llvm-project/pull/227595


More information about the cfe-commits mailing list