[WinEH] Fix two minor issues in __CxxFrameHandler3 tables

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.

llvm-svn: 249578
This commit is contained in:
Reid Kleckner 2015-10-07 17:49:32 +00:00
parent fc0ad42516
commit 33bd2d99d8
4 changed files with 12 additions and 12 deletions

View 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;

View 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;
}

View 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);
}
}
}

View 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