Fixing a bug with optimized catch-all handlers in WinEHPrepare
authorAndrew Kaylor <andrew.kaylor@intel.com>
Fri, 27 Mar 2015 22:31:12 +0000 (22:31 +0000)
committerAndrew Kaylor <andrew.kaylor@intel.com>
Fri, 27 Mar 2015 22:31:12 +0000 (22:31 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233439 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/WinEHPrepare.cpp

index 3f9aaec366e4d37e330b13fd566efb94a5f35818..e35b94f1d369c84bacf563e324a6c9725bc66788 100644 (file)
@@ -126,6 +126,7 @@ public:
     return mapIfEHLoad(Load, SelectorStores, SelectorStoreAddrs);
   }
 
+  bool isOriginLandingPadBlock(const BasicBlock *BB) const;
   bool isLandingPadSpecificInst(const Instruction *Inst) const;
 
   void remapSelector(ValueToValueMapTy &VMap, Value *MappedValue) const;
@@ -840,6 +841,10 @@ void LandingPadMap::mapLandingPad(const LandingPadInst *LPad) {
   }
 }
 
+bool LandingPadMap::isOriginLandingPadBlock(const BasicBlock *BB) const {
+  return BB->getLandingPadInst() == OriginLPad;
+}
+
 bool LandingPadMap::isLandingPadSpecificInst(const Instruction *Inst) const {
   if (Inst == OriginLPad)
     return true;
@@ -981,11 +986,12 @@ WinEHCatchDirector::handleEndCatch(ValueToValueMapTy &VMap,
 
   // The end catch call can occur in one of two places: either in a
   // landingpad block that is part of the catch handlers exception mechanism,
-  // or at the end of the catch block.  If it occurs in a landing pad, we must
-  // skip it and continue so that the landing pad gets cloned.
-  // FIXME: This case isn't fully supported yet and shouldn't turn up in any
-  //        of the test cases until it is.
-  if (IntrinCall->getParent()->isLandingPad())
+  // or at the end of the catch block.  However, a catch-all handler may call
+  // end catch from the original landing pad.  If the call occurs in a nested
+  // landing pad block, we must skip it and continue so that the landing pad
+  // gets cloned.
+  auto *ParentBB = IntrinCall->getParent();
+  if (ParentBB->isLandingPad() && !LPadMap.isOriginLandingPadBlock(ParentBB))
     return CloningDirector::SkipInstruction;
 
   // If an end catch occurs anywhere else the next instruction should be an
@@ -1475,6 +1481,9 @@ CleanupHandler *WinEHPrepare::findCleanupHandler(BasicBlock *StartBB,
             continue;
           if (Inst == Branch)
             continue;
+          // This can happen with a catch-all handler.
+          if (match(Inst, m_Intrinsic<Intrinsic::eh_begincatch>()))
+            return nullptr;
           if (match(Inst, m_Intrinsic<Intrinsic::eh_endcatch>()))
             continue;
           // Anything else makes this interesting cleanup code.