r234448 - [WinEH] Don't wrap cleanups in terminate actions

Reid Kleckner reid at kleckner.net
Wed Apr 8 15:48:50 PDT 2015


Author: rnk
Date: Wed Apr  8 17:48:50 2015
New Revision: 234448

URL: http://llvm.org/viewvc/llvm-project?rev=234448&view=rev
Log:
[WinEH] Don't wrap cleanups in terminate actions

_CxxFrameHandler3 calls terminate if a cleanup action throws, regardless
of what bits you put in the xdata tables. There's no need to model this
in the IR, since we just have to take it out later.

Modified:
    cfe/trunk/lib/CodeGen/CGCleanup.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp

Modified: cfe/trunk/lib/CodeGen/CGCleanup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCleanup.cpp?rev=234448&r1=234447&r2=234448&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCleanup.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCleanup.cpp Wed Apr  8 17:48:50 2015
@@ -471,8 +471,14 @@ static void EmitCleanup(CodeGenFunction
                         EHScopeStack::Cleanup *Fn,
                         EHScopeStack::Cleanup::Flags flags,
                         llvm::Value *ActiveFlag) {
-  // EH cleanups always occur within a terminate scope.
-  if (flags.isForEHCleanup()) CGF.EHStack.pushTerminate();
+  // Itanium EH cleanups occur within a terminate scope. Microsoft SEH doesn't
+  // have this behavior, and the Microsoft C++ runtime will call terminate for
+  // us if the cleanup throws.
+  bool PushedTerminate = false;
+  if (flags.isForEHCleanup() && !CGF.getTarget().getCXXABI().isMicrosoft()) {
+    CGF.EHStack.pushTerminate();
+    PushedTerminate = true;
+  }
 
   // If there's an active flag, load it and skip the cleanup if it's
   // false.
@@ -495,7 +501,8 @@ static void EmitCleanup(CodeGenFunction
     CGF.EmitBlock(ContBB);
 
   // Leave the terminate scope.
-  if (flags.isForEHCleanup()) CGF.EHStack.popTerminate();
+  if (PushedTerminate)
+    CGF.EHStack.popTerminate();
 }
 
 static void ForwardPrebranchedFallthrough(llvm::BasicBlock *Exit,

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp?rev=234448&r1=234447&r2=234448&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp Wed Apr  8 17:48:50 2015
@@ -165,6 +165,29 @@ C::C() { foo(); }
 // WIN32:      getelementptr inbounds i8, i8* %{{.*}}, i64 4
 // WIN32-NOT:  load
 // WIN32:      bitcast i8* %{{.*}} to %"struct.crash_on_partial_destroy::A"*
-// WIN32:      invoke x86_thiscallcc void @"\01??1A at crash_on_partial_destroy@@UAE at XZ"
+// WIN32:      call x86_thiscallcc void @"\01??1A at crash_on_partial_destroy@@UAE at XZ"
 // WIN32: }
 }
+
+namespace dont_call_terminate {
+struct C {
+  ~C();
+};
+void g();
+void f() {
+  C c;
+  g();
+}
+
+// WIN32-LABEL: define void @"\01?f at dont_call_terminate@@YAXXZ"()
+// WIN32: invoke void @"\01?g at dont_call_terminate@@YAXXZ"()
+// WIN32-NEXT: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
+//
+// WIN32: [[cont]]
+// WIN32: call x86_thiscallcc void @"\01??1C at dont_call_terminate@@QAE at XZ"({{.*}})
+//
+// WIN32: [[lpad]]
+// WIN32-NEXT: landingpad
+// WIN32-NEXT: cleanup
+// WIN32: call x86_thiscallcc void @"\01??1C at dont_call_terminate@@QAE at XZ"({{.*}})
+}





More information about the cfe-commits mailing list