llvm.org GIT mirror llvm / dcae508
[WinEH] Allocate the registration node before the catch objects The CatchObjOffset is relative to the end of the EH registration node for 32-bit x86 WinEH targets. A special sentinel value, 0, is used to indicate that no catch object should be initialized. This means that a catch object allocated immediately before the registration node would be assigned a CatchObjOffset of 0, leading the runtime to believe that a catch object should not be initialized. To handle this, allocate the registration node prior to any other frame object. This will ensure that catch objects will not be allocated before the registration node. This fixes PR26757. Differential Revision: http://reviews.llvm.org/D17689 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@262294 91177308-0d34-0410-b5e6-96231b3b80d8 David Majnemer 3 years ago
4 changed file(s) with 48 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
792792 const MCExpr *FrameAllocOffsetRef = nullptr;
793793 if (HT.CatchObj.FrameIndex != INT_MAX) {
794794 int Offset = getFrameIndexOffset(HT.CatchObj.FrameIndex, FuncInfo);
795 assert(Offset != 0 && "Illegal offset for catch object!");
795796 FrameAllocOffsetRef = MCConstantExpr::create(Offset, Asm->OutContext);
796797 } else {
797798 FrameAllocOffsetRef = MCConstantExpr::create(0, Asm->OutContext);
708708
709709 SmallVector ObjectsToAllocate;
710710
711 int EHRegNodeFrameIndex = INT_MAX;
712 if (const WinEHFuncInfo *FuncInfo = Fn.getWinEHFuncInfo())
713 EHRegNodeFrameIndex = FuncInfo->EHRegNodeFrameIndex;
714
711715 // Then prepare to assign frame offsets to stack objects that are not used to
712716 // spill callee saved registers.
713717 for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) {
722726 continue;
723727 if (MFI->getStackProtectorIndex() == (int)i)
724728 continue;
729 if (EHRegNodeFrameIndex == (int)i)
730 continue;
725731 if (ProtectedObjs.count(i))
726732 continue;
727733
728734 // Add the objects that we need to allocate to our working set.
729735 ObjectsToAllocate.push_back(i);
730736 }
737
738 // Allocate the EH registration node first if one is present.
739 if (EHRegNodeFrameIndex != INT_MAX)
740 AdjustStackOffset(MFI, EHRegNodeFrameIndex, StackGrowsDown, Offset,
741 MaxAlign, Skew);
742
731743 // Give the targets a chance to order the objects the way they like it.
732744 if (Fn.getTarget().getOptLevel() != CodeGenOpt::None &&
733745 Fn.getTarget().Options.StackSymbolOrdering)
5050 ; CHECK: "?dtor$2@?0?passes_two@4HA":
5151 ; CHECK: pushl %ebp
5252 ; CHECK: subl $8, %esp
53 ; CHECK: addl $16, %ebp
53 ; CHECK: addl $12, %ebp
5454 ; CHECK: {{movl|leal}} -{{[0-9]+}}(%ebp), %ecx
5555 ; CHECK: calll "??1A@@QAE@XZ"
5656 ; CHECK: addl $8, %esp
0 ; RUN: llc < %s | FileCheck %s
1 target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
2 target triple = "i386-pc-windows-msvc"
3
4 declare void @throw()
5
6 define void @test1() personality i32 (...)* @__CxxFrameHandler3 {
7 %e = alloca i8, align 4
8 invoke void @throw()
9 to label %.noexc unwind label %catch.dispatch
10
11 .noexc:
12 unreachable
13
14 catch.object.Exception:
15 %cp = catchpad within %cs [i8* null, i32 0, i8* %e]
16 catchret from %cp to label %catchhandler
17
18 catch.dispatch:
19 %cs = catchswitch within none [label %catch.object.Exception] unwind to caller
20
21 catchhandler:
22 call void @use(i8* %e)
23 ret void
24 }
25
26 ; CHECK-LABEL: $handlerMap$0$test1:
27 ; CHECK: .long 0
28 ; CHECK-NEXT: .long 0
29 ; CHECK-NEXT: .long -20
30
31 declare void @use(i8*)
32
33 declare i32 @__CxxFrameHandler3(...)