[WinEH] CatchHandler which don't have catch objects in StackColoring
authorDavid Majnemer <david.majnemer@gmail.com>
Fri, 8 Jan 2016 17:24:47 +0000 (17:24 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Fri, 8 Jan 2016 17:24:47 +0000 (17:24 +0000)
StackColoring rewrites the frame indicies of operations involving
allocas if it can find that the life time of two objects do not overlap.
MSVC EH needs to be kept aware of this if happens in the event that a
catch object has moved around.  However, we represent the non-existance
of a catch object with a sentinel frame index (INT_MAX).  This sentinel
also happens to be the EmptyKey of the SlotRemap DenseMap.  Testing for
whether or not we need to translate the frame index fails in this case
because we call the count method on the DenseMap with the EmptyKey,
leading to assertions.  Instead, check if it is our sentinel value
before trying to look into the DenseMap.

This fixes PR26073.

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

lib/CodeGen/StackColoring.cpp
test/CodeGen/X86/catchpad-lifetime.ll

index d0c0cf777028be7b91b37d24d6e67e6474981e8c..7b5203815172b2dd4b66e721d22b894953d4e5dc 100644 (file)
@@ -571,10 +571,12 @@ void StackColoring::remapInstructions(DenseMap<int, int> &SlotRemap) {
       }
     }
 
+  // Update the location of C++ catch objects for the MSVC personality routine.
   if (WinEHFuncInfo *EHInfo = MF->getWinEHFuncInfo())
     for (WinEHTryBlockMapEntry &TBME : EHInfo->TryBlockMap)
       for (WinEHHandlerType &H : TBME.HandlerArray)
-        if (SlotRemap.count(H.CatchObj.FrameIndex))
+        if (H.CatchObj.FrameIndex != INT_MAX &&
+            SlotRemap.count(H.CatchObj.FrameIndex))
           H.CatchObj.FrameIndex = SlotRemap[H.CatchObj.FrameIndex];
 
   DEBUG(dbgs()<<"Fixed "<<FixedMemOp<<" machine memory operands.\n");
index 38fc981d2b7fdbb20d0b2f9ab5f4beb7fa354cb5..dfd75334561fa14029e1b2d6b327900cb3330ce6 100644 (file)
@@ -44,6 +44,44 @@ unreachable:                                      ; preds = %entry
 ; CHECK-LABEL: $cppxdata$test1:
 ; CHECK: .long   32                      # CatchObjOffset
 
+define void @test2() personality i32 (...)* @__CxxFrameHandler3 {
+entry:
+  %alloca2 = alloca i8*, align 4
+  %alloca1 = alloca i8*, align 4
+  store volatile i8* null, i8** %alloca1
+  invoke void @throw()
+          to label %unreachable unwind label %catch.dispatch
+
+; CHECK-LABEL: test2:
+; CHECK: movq  $0, -16(%rbp)
+; CHECK: callq throw
+
+catch.dispatch:                                   ; preds = %entry
+  %cs = catchswitch within none [label %catch.pad] unwind to caller
+
+catch.pad:                                        ; preds = %catch.dispatch
+  %cp = catchpad within %cs [i8* null, i32 0, i8** null]
+  store volatile i8* null, i8** %alloca1
+  %bc1 = bitcast i8** %alloca1 to i8*
+  call void @llvm.lifetime.end(i64 4, i8* nonnull %bc1)
+  %bc2 = bitcast i8** %alloca2 to i8*
+  call void @llvm.lifetime.start(i64 4, i8* %bc2)
+  store volatile i8* null, i8** %alloca1
+  unreachable
+
+; CHECK-LABEL: "?catch$2@?0?test2@4HA"
+; CHECK: movq  $0, -16(%rbp)
+; CHECK: movq  $0, -16(%rbp)
+; CHECK: ud2
+
+unreachable:                                      ; preds = %entry
+  unreachable
+}
+
+; CHECK-LABEL: $cppxdata$test2:
+; CHECK: .long   0                       # CatchObjOffset
+
+
 ; Function Attrs: argmemonly nounwind
 declare void @llvm.lifetime.start(i64, i8* nocapture) #0