r247349 - [SEH] Use cleanupendpad so that WinEHPrepare gets the coloring right

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 10 15:11:14 PDT 2015


Author: rnk
Date: Thu Sep 10 17:11:13 2015
New Revision: 247349

URL: http://llvm.org/viewvc/llvm-project?rev=247349&view=rev
Log:
[SEH] Use cleanupendpad so that WinEHPrepare gets the coloring right

Cleanupendpad is a lot like catchendpad, so we can reuse the same
EHScopeStack type.

Modified:
    cfe/trunk/lib/CodeGen/CGCleanup.cpp
    cfe/trunk/lib/CodeGen/CGCleanup.h
    cfe/trunk/lib/CodeGen/CGException.cpp
    cfe/trunk/lib/CodeGen/EHScopeStack.h
    cfe/trunk/test/CodeGen/exceptions-seh-new.c

Modified: cfe/trunk/lib/CodeGen/CGCleanup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCleanup.cpp?rev=247349&r1=247348&r2=247349&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCleanup.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCleanup.cpp Thu Sep 10 17:11:13 2015
@@ -262,10 +262,10 @@ void EHScopeStack::pushTerminate() {
   InnermostEHScope = stable_begin();
 }
 
-void EHScopeStack::pushCatchEnd(llvm::BasicBlock *CatchEndBlockBB) {
-  char *Buffer = allocate(EHCatchEndScope::getSize());
-  auto *CES = new (Buffer) EHCatchEndScope(InnermostEHScope);
-  CES->setCachedEHDispatchBlock(CatchEndBlockBB);
+void EHScopeStack::pushPadEnd(llvm::BasicBlock *PadEndBB) {
+  char *Buffer = allocate(EHPadEndScope::getSize());
+  auto *CES = new (Buffer) EHPadEndScope(InnermostEHScope);
+  CES->setCachedEHDispatchBlock(PadEndBB);
   InnermostEHScope = stable_begin();
 }
 

Modified: cfe/trunk/lib/CodeGen/CGCleanup.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCleanup.h?rev=247349&r1=247348&r2=247349&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCleanup.h (original)
+++ cfe/trunk/lib/CodeGen/CGCleanup.h Thu Sep 10 17:11:13 2015
@@ -101,7 +101,7 @@ protected:
   };
 
 public:
-  enum Kind { Cleanup, Catch, Terminate, Filter, CatchEnd };
+  enum Kind { Cleanup, Catch, Terminate, Filter, PadEnd };
 
   EHScope(Kind kind, EHScopeStack::stable_iterator enclosingEHScope)
     : CachedLandingPad(nullptr), CachedEHDispatchBlock(nullptr),
@@ -474,14 +474,14 @@ public:
   }
 };
 
-class EHCatchEndScope : public EHScope {
+class EHPadEndScope : public EHScope {
 public:
-  EHCatchEndScope(EHScopeStack::stable_iterator enclosingEHScope)
-      : EHScope(CatchEnd, enclosingEHScope) {}
-  static size_t getSize() { return sizeof(EHCatchEndScope); }
+  EHPadEndScope(EHScopeStack::stable_iterator enclosingEHScope)
+      : EHScope(PadEnd, enclosingEHScope) {}
+  static size_t getSize() { return sizeof(EHPadEndScope); }
 
   static bool classof(const EHScope *scope) {
-    return scope->getKind() == CatchEnd;
+    return scope->getKind() == PadEnd;
   }
 };
 
@@ -523,8 +523,8 @@ public:
       Size = EHTerminateScope::getSize();
       break;
 
-    case EHScope::CatchEnd:
-      Size = EHCatchEndScope::getSize();
+    case EHScope::PadEnd:
+      Size = EHPadEndScope::getSize();
       break;
     }
     Ptr += llvm::RoundUpToAlignment(Size, ScopeStackAlignment);
@@ -574,12 +574,12 @@ inline void EHScopeStack::popTerminate()
   deallocate(EHTerminateScope::getSize());
 }
 
-inline void EHScopeStack::popCatchEnd() {
+inline void EHScopeStack::popPadEnd() {
   assert(!empty() && "popping exception stack when not empty");
 
-  EHCatchEndScope &scope = cast<EHCatchEndScope>(*begin());
+  EHPadEndScope &scope = cast<EHPadEndScope>(*begin());
   InnermostEHScope = scope.getEnclosingEHScope();
-  deallocate(EHCatchEndScope::getSize());
+  deallocate(EHPadEndScope::getSize());
 }
 
 inline EHScopeStack::iterator EHScopeStack::find(stable_iterator sp) const {

Modified: cfe/trunk/lib/CodeGen/CGException.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=247349&r1=247348&r2=247349&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGException.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGException.cpp Thu Sep 10 17:11:13 2015
@@ -601,8 +601,8 @@ CodeGenFunction::getEHDispatchBlock(EHSc
       dispatchBlock = getTerminateHandler();
       break;
 
-    case EHScope::CatchEnd:
-      llvm_unreachable("CatchEnd unnecessary for Itanium!");
+    case EHScope::PadEnd:
+      llvm_unreachable("PadEnd unnecessary for Itanium!");
     }
     scope.setCachedEHDispatchBlock(dispatchBlock);
   }
@@ -645,8 +645,8 @@ CodeGenFunction::getMSVCDispatchBlock(EH
     DispatchBlock->setName("terminate");
     break;
 
-  case EHScope::CatchEnd:
-    llvm_unreachable("CatchEnd dispatch block missing!");
+  case EHScope::PadEnd:
+    llvm_unreachable("PadEnd dispatch block missing!");
   }
   EHS.setCachedEHDispatchBlock(DispatchBlock);
   return DispatchBlock;
@@ -662,7 +662,7 @@ static bool isNonEHScope(const EHScope &
   case EHScope::Filter:
   case EHScope::Catch:
   case EHScope::Terminate:
-  case EHScope::CatchEnd:
+  case EHScope::PadEnd:
     return false;
   }
 
@@ -721,8 +721,8 @@ llvm::BasicBlock *CodeGenFunction::EmitL
   case EHScope::Terminate:
     return getTerminateLandingPad();
 
-  case EHScope::CatchEnd:
-    llvm_unreachable("CatchEnd unnecessary for Itanium!");
+  case EHScope::PadEnd:
+    llvm_unreachable("PadEnd unnecessary for Itanium!");
 
   case EHScope::Catch:
   case EHScope::Cleanup:
@@ -790,8 +790,8 @@ llvm::BasicBlock *CodeGenFunction::EmitL
     case EHScope::Catch:
       break;
 
-    case EHScope::CatchEnd:
-      llvm_unreachable("CatchEnd unnecessary for Itanium!");
+    case EHScope::PadEnd:
+      llvm_unreachable("PadEnd unnecessary for Itanium!");
     }
 
     EHCatchScope &catchScope = cast<EHCatchScope>(*I);
@@ -1028,7 +1028,7 @@ void CodeGenFunction::ExitCXXTryStmt(con
                         isa<CXXConstructorDecl>(CurCodeDecl);
 
   if (CatchEndBlockBB)
-    EHStack.pushCatchEnd(CatchEndBlockBB);
+    EHStack.pushPadEnd(CatchEndBlockBB);
 
   // Perversely, we emit the handlers backwards precisely because we
   // want them to appear in source order.  In all of these cases, the
@@ -1083,7 +1083,7 @@ void CodeGenFunction::ExitCXXTryStmt(con
   EmitBlock(ContBB);
   incrementProfileCounter(&S);
   if (CatchEndBlockBB)
-    EHStack.popCatchEnd();
+    EHStack.popPadEnd();
 }
 
 namespace {
@@ -1397,8 +1397,10 @@ void CodeGenFunction::EmitSEHTryStmt(con
 namespace {
 struct PerformSEHFinally final : EHScopeStack::Cleanup {
   llvm::Function *OutlinedFinally;
-  PerformSEHFinally(llvm::Function *OutlinedFinally)
-      : OutlinedFinally(OutlinedFinally) {}
+  EHScopeStack::stable_iterator EnclosingScope;
+  PerformSEHFinally(llvm::Function *OutlinedFinally,
+                    EHScopeStack::stable_iterator EnclosingScope)
+      : OutlinedFinally(OutlinedFinally), EnclosingScope(EnclosingScope) {}
 
   void Emit(CodeGenFunction &CGF, Flags F) override {
     ASTContext &Context = CGF.getContext();
@@ -1423,7 +1425,28 @@ struct PerformSEHFinally final : EHScope
         CGM.getTypes().arrangeFreeFunctionCall(Args, FPT,
                                                /*chainCall=*/false);
 
+    // If this is the normal cleanup or using the old EH IR, just emit the call.
+    if (!F.isForEHCleanup() || !CGM.getCodeGenOpts().NewMSEH) {
+      CGF.EmitCall(FnInfo, OutlinedFinally, ReturnValueSlot(), Args);
+      return;
+    }
+
+    // Build a cleanupendpad to unwind through.
+    llvm::BasicBlock *CleanupBB = CGF.Builder.GetInsertBlock();
+    llvm::BasicBlock *CleanupEndBB = CGF.createBasicBlock("ehcleanup.end");
+    llvm::Instruction *PadInst = CleanupBB->getFirstNonPHI();
+    auto *CPI = cast<llvm::CleanupPadInst>(PadInst);
+    CGBuilderTy(CGF, CleanupEndBB)
+        .CreateCleanupEndPad(CPI, CGF.getEHDispatchBlock(EnclosingScope));
+
+    // Push and pop the cleanupendpad around the call.
+    CGF.EHStack.pushPadEnd(CleanupEndBB);
     CGF.EmitCall(FnInfo, OutlinedFinally, ReturnValueSlot(), Args);
+    CGF.EHStack.popPadEnd();
+
+    // Insert the catchendpad block here.
+    CGF.CurFn->getBasicBlockList().insertAfter(CGF.Builder.GetInsertBlock(),
+                                               CleanupEndBB);
   }
 };
 }
@@ -1779,7 +1802,8 @@ void CodeGenFunction::EnterSEHTryStmt(co
         HelperCGF.GenerateSEHFinallyFunction(*this, *Finally);
 
     // Push a cleanup for __finally blocks.
-    EHStack.pushCleanup<PerformSEHFinally>(NormalAndEHCleanup, FinallyFunc);
+    EHStack.pushCleanup<PerformSEHFinally>(NormalAndEHCleanup, FinallyFunc,
+                                           EHStack.getInnermostEHScope());
     return;
   }
 

Modified: cfe/trunk/lib/CodeGen/EHScopeStack.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/EHScopeStack.h?rev=247349&r1=247348&r2=247349&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/EHScopeStack.h (original)
+++ cfe/trunk/lib/CodeGen/EHScopeStack.h Thu Sep 10 17:11:13 2015
@@ -334,9 +334,9 @@ public:
   /// Pops a terminate handler off the stack.
   void popTerminate();
 
-  void pushCatchEnd(llvm::BasicBlock *CatchEndBlockBB);
+  void pushPadEnd(llvm::BasicBlock *PadEndBB);
 
-  void popCatchEnd();
+  void popPadEnd();
 
   // Returns true iff the current scope is either empty or contains only
   // lifetime markers, i.e. no real cleanup code

Modified: cfe/trunk/test/CodeGen/exceptions-seh-new.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/exceptions-seh-new.c?rev=247349&r1=247348&r2=247349&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/exceptions-seh-new.c (original)
+++ cfe/trunk/test/CodeGen/exceptions-seh-new.c Thu Sep 10 17:11:13 2015
@@ -182,8 +182,12 @@ int basic_finally(int g) {
 // CHECK: [[cleanuppad]]
 // CHECK: %[[padtoken:[^ ]*]] = cleanuppad []
 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
-// CHECK: call void @"\01?fin$0 at 0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
+// CHECK: invoke void @"\01?fin$0 at 0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
+// CHECK:     to label %[[cleanupcont:[^ ]*]] unwind label %[[cleanupend:[^ ]*]]
+// CHECK: [[cleanupcont]]
 // CHECK: cleanupret %[[padtoken]] unwind to caller
+// CHECK: [[cleanupend]]
+// CHECK: cleanupendpad %[[padtoken]] unwind to caller
 
 // CHECK: define internal void @"\01?fin$0 at 0@basic_finally@@"({{i8( zeroext)?}} %abnormal_termination, i8* %frame_pointer)
 // CHECK:   call i8* @llvm.localrecover(i8* bitcast (i32 (i32)* @basic_finally to i8*), i8* %frame_pointer, i32 0)




More information about the cfe-commits mailing list