================
@@ -325,19 +374,47 @@ mlir::LogicalResult 
ItaniumEHLowering::lowerFunc(cir::FuncOp funcOp) {
   if (!funcOp.getPersonality())
     funcOp.setPersonality(kGxxPersonality);
 
-  // Lower each initiate and all EH ops connected to it. The token map is
-  // shared across all initiate operations. Multiple initiates may flow into 
the
-  // same dispatch block, and the map ensures the arguments are registered
-  // only once. Dispatch ops are scheduled for deferred removal so that sibling
-  // initiates can still read catch types from a shared dispatch.
+  // Compute, read-only and before any destructive lowering, the dispatches 
each
+  // initiate's exception can reach (innermost first; more than one for nested
+  // try/catch).  A landing pad's catch types are a property of the EH graph, 
so
+  // deriving them here keeps them independent of the order in which the
+  // destructive per-initiate traversal in lowerEhInitiate tears down shared
+  // token-graph edges.  Otherwise a sibling or outer dispatch could be missed,
+  // leaving a landing pad without its catch clause (it would resume past the
+  // handler to std::terminate) or an un-lowered leftover dispatch.
+  llvm::DenseMap<mlir::Operation *, SmallVector<cir::EhDispatchOp>>
+      reachedDispatches;
+  llvm::DenseMap<mlir::Operation *, bool> reachesCleanup;
+  SmallVector<cir::EhDispatchOp> dispatchesToLower;
+  for (cir::EhInitiateOp initiateOp : initiateOps) {
+    SmallVector<cir::EhDispatchOp> reached;
+    bool cleanupOnPath = false;
+    collectReachableDispatches(initiateOp.getEhToken(), reached, 
cleanupOnPath);
+    for (cir::EhDispatchOp dispatch : reached)
+      if (!llvm::is_contained(dispatchesToLower, dispatch))
+        dispatchesToLower.push_back(dispatch);
+    reachedDispatches[initiateOp.getOperation()] = std::move(reached);
+    reachesCleanup[initiateOp.getOperation()] = cleanupOnPath;
+  }
+
   EhTokenMap ehTokenMap;
   SmallVector<mlir::Operation *> deadOps;
   for (cir::EhInitiateOp initiateOp : initiateOps)
-    if (mlir::failed(lowerEhInitiate(initiateOp, ehTokenMap, deadOps)))
+    if (mlir::failed(lowerEhInitiate(
+            initiateOp, reachedDispatches[initiateOp.getOperation()],
+            reachesCleanup[initiateOp.getOperation()], ehTokenMap, deadOps)))
       return mlir::failure();
 
+  // Lower each dispatch exactly once.  Every initiate's token block-argument
+  // (ptr, u32) replacements are registered in ehTokenMap by now, so each
+  // dispatch's own (exnPtr, typeId) pair is available.
+  for (cir::EhDispatchOp dispatch : dispatchesToLower) {
+    auto [exnPtr, typeId] = ehTokenMap.lookup(dispatch.getEhToken());
----------------
andykaylor wrote:

Can you assert that this doesn't return null values?

https://github.com/llvm/llvm-project/pull/205638
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to