[WinEH] Fix two minor issues in __CxxFrameHandler3 tables
authorReid Kleckner <rnk@google.com>
Wed, 7 Oct 2015 17:49:32 +0000 (17:49 +0000)
committerReid Kleckner <rnk@google.com>
Wed, 7 Oct 2015 17:49:32 +0000 (17:49 +0000)
There was an off-by-one bug in ip2state tables which manifested when one
call immediately preceded the try-range of the next. The return address
of the previous call would appear to be within the try range of the next
scope, resulting in extra destructors or catches running.

We also computed the wrong offset for catch parameter stack objects. The
offset should be from RSP, not from RBP.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249578 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/TargetFrameLowering.h
lib/CodeGen/AsmPrinter/WinException.cpp
lib/CodeGen/PrologEpilogInserter.cpp
test/CodeGen/X86/win-catchpad.ll

index 2e8c178914e731135a6036d912de86a1a9acb448..9585f7c34984fa41fae6756d98d8fa046182b66e 100644 (file)
@@ -236,10 +236,11 @@ public:
                                      unsigned &FrameReg) const;
 
   /// Same as above, except that the 'base register' will always be RSP, not
-  /// RBP on x86.  This is used exclusively for lowering STATEPOINT nodes.
+  /// RBP on x86. This is generally used for emitting statepoint or EH tables
+  /// that use offsets from RSP.
   /// TODO: This should really be a parameterizable choice.
   virtual int getFrameIndexReferenceFromSP(const MachineFunction &MF, int FI,
-                                          unsigned &FrameReg) const {
+                                           unsigned &FrameReg) const {
     // default to calling normal version, we override this on x86 only
     llvm_unreachable("unimplemented for non-x86");
     return 0;
index 4f1d5cb864a7a55b350a8ddd5cd033df424c3fbe..bc2c9ee635cfb7a56c415c7f41e1a74402f9ca85 100644 (file)
@@ -791,7 +791,7 @@ void WinException::computeIP2StateTable(
       // Emit an entry indicating that PCs after 'Label' have this EH state.
       if (I.State != LastEHState)
         IPToStateTable.push_back(
-            std::make_pair(create32bitRef(I.BeginLabel), I.State));
+            std::make_pair(getLabelPlusOne(I.BeginLabel), I.State));
       LastEHState = I.State;
       LastEndLabel = I.EndLabel;
     }
index 63825b5dde90f3d9baa21b744a58c8c9cbdc8980..495da5c07d11e91ee05ba9609fdf19d6c93ca0cd 100644 (file)
@@ -820,12 +820,11 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) {
           Fn, FuncInfo.UnwindHelpFrameIdx, FrameReg);
     for (WinEHTryBlockMapEntry &TBME : FuncInfo.TryBlockMap) {
       for (WinEHHandlerType &H : TBME.HandlerArray) {
-        unsigned UnusedReg;
         if (H.CatchObj.FrameIndex == INT_MAX)
           H.CatchObj.FrameOffset = INT_MAX;
         else
-          H.CatchObj.FrameOffset =
-              TFI.getFrameIndexReference(Fn, H.CatchObj.FrameIndex, UnusedReg);
+          H.CatchObj.FrameOffset = TFI.getFrameIndexReferenceFromSP(
+              Fn, H.CatchObj.FrameIndex, FrameReg);
       }
     }
   }
index 45d1085f3ad74aef9dfbfa1f668734ca67edd635..67875f2306033530408b4a9986fcd1c8846b90c5 100644 (file)
@@ -120,7 +120,7 @@ catchendblock:                                    ; preds = %catch, %catch.2, %c
 ; X86: $handlerMap$0$try_catch_catch:
 ; X86-NEXT:   .long   0
 ; X86-NEXT:   .long   "??_R0H@8"
-; X86-NEXT:   .long   -20
+; X86-NEXT:   .long   24
 ; X86-NEXT:   .long   "?catch$[[catch1bb]]@?0?try_catch_catch@4HA"
 ; X86-NEXT:   .long   64
 ; X86-NEXT:   .long   0
@@ -156,7 +156,7 @@ catchendblock:                                    ; preds = %catch, %catch.2, %c
 ; X64: .seh_endprologue
 ; X64-DAG: .Ltmp4
 ; X64-DAG: leaq -[[local_offs]](%rbp), %rdx
-; X64-DAG: movl [[e_addr:[-0-9]+]](%rbp), %ecx
+; X64-DAG: movl -4(%rbp), %ecx
 ; X64: callq f
 ; X64: leaq [[contbb]](%rip), %rax
 ; X64-NEXT: addq $32, %rsp
@@ -204,7 +204,7 @@ catchendblock:                                    ; preds = %catch, %catch.2, %c
 ; X64-NEXT:   .long   0
 ; X64-NEXT:   .long   "??_R0H@8"@IMGREL
 ; FIXME: This should probably be offset from rsp, not rbp.
-; X64-NEXT:   .long   [[e_addr]]
+; X64-NEXT:   .long   44
 ; X64-NEXT:   .long   "?catch$[[catch1bb]]@?0?try_catch_catch@4HA"@IMGREL
 ; X64-NEXT:   .long   56
 ; X64-NEXT:   .long   64
@@ -216,9 +216,9 @@ catchendblock:                                    ; preds = %catch, %catch.2, %c
 ; X64: $ip2state$try_catch_catch:
 ; X64-NEXT: .long   .Lfunc_begin0@IMGREL
 ; X64-NEXT: .long   -1
-; X64-NEXT: .long   .Ltmp0@IMGREL
+; X64-NEXT: .long   .Ltmp0@IMGREL+1
 ; X64-NEXT: .long   0
-; X64-NEXT: .long   .Ltmp4@IMGREL
+; X64-NEXT: .long   .Ltmp4@IMGREL+1
 ; X64-NEXT: .long   1
 ; X64-NEXT: .long   .Ltmp3@IMGREL+1
 ; X64-NEXT: .long   -1
@@ -353,7 +353,7 @@ catchendblock:
 ; X64-LABEL: $ip2state$branch_to_normal_dest:
 ; X64-NEXT: .long   .Lfunc_begin1@IMGREL
 ; X64-NEXT: .long   -1
-; X64-NEXT: .long   .Ltmp[[before_call]]@IMGREL
+; X64-NEXT: .long   .Ltmp[[before_call]]@IMGREL+1
 ; X64-NEXT: .long   0
 ; X64-NEXT: .long   .Ltmp[[after_call]]@IMGREL+1
 ; X64-NEXT: .long   -1