Don't emit .seh_handler directives for any cleanup funclets
authorReid Kleckner <rnk@google.com>
Thu, 8 Dec 2016 20:38:46 +0000 (20:38 +0000)
committerReid Kleckner <rnk@google.com>
Thu, 8 Dec 2016 20:38:46 +0000 (20:38 +0000)
We were falsely claiming that we had an LSDA for the relevant EH
personality before this change, which could lead to the EH machinery
interpreting random adjacent data as an LSDA.

Fixes PR31317

This change is safe because cleanups can't contain exception handlers
today. We do these things to maintain that invariant:
- C++ destructors are naturally out-of-line
- __finally blocks are outlined in clang
- LLVM's inliner will not inline EH constructs into cleanups

llvm-svn: 289101

llvm/lib/CodeGen/AsmPrinter/WinException.cpp
llvm/test/CodeGen/X86/seh-catchpad.ll

index 75cb43d..919fc48 100644 (file)
@@ -221,12 +221,12 @@ void WinException::beginFunclet(const MachineBasicBlock &MBB,
     const MCSymbol *PersHandlerSym =
         TLOF.getCFIPersonalitySymbol(PerFn, Asm->TM, MMI);
 
-    // Classify the personality routine so that we may reason about it.
-    EHPersonality Per = classifyEHPersonality(PerFn);
-
-    // Do not emit a .seh_handler directive if it is a C++ cleanup funclet.
-    if (Per != EHPersonality::MSVC_CXX ||
-        !CurrentFuncletEntry->isCleanupFuncletEntry())
+    // Do not emit a .seh_handler directives for cleanup funclets.
+    // FIXME: This means cleanup funclets cannot handle exceptions. Given that
+    // Clang doesn't produce EH constructs inside cleanup funclets and LLVM's
+    // inliner doesn't allow inlining them, this isn't a major problem in
+    // practice.
+    if (!CurrentFuncletEntry->isCleanupFuncletEntry())
       Asm->OutStreamer->EmitWinEHHandler(PersHandlerSym, true, true);
   }
 }
index 99ed454..b8f1753 100644 (file)
@@ -147,7 +147,7 @@ __except.ret:                                     ; preds = %catch.dispatch.7
 
 ; CHECK: "?dtor$[[finbb]]@?0?main@4HA":
 ; CHECK: .seh_proc "?dtor$[[finbb]]@?0?main@4HA"
-; CHECK:         .seh_handler __C_specific_handler, @unwind, @except
+; CHECK-NOT:         .seh_handler
 ; CHECK: .LBB1_[[finbb]]:                                # %ehcleanup
 ; CHECK:         movq    %rdx, 16(%rsp)
 ; CHECK:         pushq   %rbp