diff --git a/include/llvm/CodeGen/WinEHFuncInfo.h b/include/llvm/CodeGen/WinEHFuncInfo.h index f905af655c6..732b5d24952 100644 --- a/include/llvm/CodeGen/WinEHFuncInfo.h +++ b/include/llvm/CodeGen/WinEHFuncInfo.h @@ -75,6 +75,7 @@ public: void setExceptionVar(const Value *Val) { ExceptionObjectVar = Val; } void setExceptionVarIndex(int Index) { ExceptionObjectIndex = Index; } + int getExceptionVarIndex() const { return ExceptionObjectIndex; } void setReturnTargets(TinyPtrVector &Targets) { ReturnTargets = Targets; } @@ -120,8 +121,7 @@ struct WinEHUnwindMapEntry { struct WinEHHandlerType { int Adjectives; GlobalVariable *TypeDescriptor; - int CatchObjIdx; - int CatchObjOffset; + int CatchObjRecoverIdx; Function *Handler; }; diff --git a/lib/CodeGen/AsmPrinter/Win64Exception.cpp b/lib/CodeGen/AsmPrinter/Win64Exception.cpp index 7a82daa3337..676ce65dedb 100644 --- a/lib/CodeGen/AsmPrinter/Win64Exception.cpp +++ b/lib/CodeGen/AsmPrinter/Win64Exception.cpp @@ -450,9 +450,16 @@ void Win64Exception::emitCXXFrameHandler3Table(const MachineFunction *MF) { const MCSymbolRefExpr *ParentFrameOffsetRef = MCSymbolRefExpr::Create( ParentFrameOffset, MCSymbolRefExpr::VK_None, Asm->OutContext); + MCSymbol *FrameAllocOffset = + Asm->OutContext.getOrCreateFrameAllocSymbol( + GlobalValue::getRealLinkageName(F->getName()), + HT.CatchObjRecoverIdx); + const MCSymbolRefExpr *FrameAllocOffsetRef = MCSymbolRefExpr::Create( + FrameAllocOffset, MCSymbolRefExpr::VK_None, Asm->OutContext); + OS.EmitIntValue(HT.Adjectives, 4); // Adjectives OS.EmitValue(createImageRel32(HT.TypeDescriptor), 4); // Type - OS.EmitIntValue(HT.CatchObjOffset, 4); // CatchObjOffset + OS.EmitValue(FrameAllocOffsetRef, 4); // CatchObjOffset OS.EmitValue(createImageRel32(HT.Handler), 4); // Handler OS.EmitValue(ParentFrameOffsetRef, 4); // ParentFrameOffset } diff --git a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp index 987ba83b391..bfaab9e6b6b 100644 --- a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -321,9 +321,7 @@ void WinEHNumbering::createTryBlockMapEntry(int TryLow, int TryHigh, cast(CS->getAggregateElement(1)->stripPointerCasts()); } HT.Handler = cast(CH->getHandlerBlockOrFunc()); - // FIXME: We don't support catching objects yet! - HT.CatchObjIdx = INT_MAX; - HT.CatchObjOffset = 0; + HT.CatchObjRecoverIdx = CH->getExceptionVarIndex(); TBME.HandlerArray.push_back(HT); } FuncInfo.TryBlockMap.push_back(TBME); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 008d7dc2b25..710d8073fed 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -5410,8 +5410,8 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { "can only escape static allocas"); int FI = FuncInfo.StaticAllocaMap[Slot]; MCSymbol *FrameAllocSym = - MF.getMMI().getContext().getOrCreateFrameAllocSymbol(MF.getName(), - Idx); + MF.getMMI().getContext().getOrCreateFrameAllocSymbol( + GlobalValue::getRealLinkageName(MF.getName()), Idx); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, dl, TII->get(TargetOpcode::FRAME_ALLOC)) .addSym(FrameAllocSym) @@ -5431,8 +5431,8 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { auto *Idx = cast(I.getArgOperand(2)); unsigned IdxVal = unsigned(Idx->getLimitedValue(INT_MAX)); MCSymbol *FrameAllocSym = - MF.getMMI().getContext().getOrCreateFrameAllocSymbol(Fn->getName(), - IdxVal); + MF.getMMI().getContext().getOrCreateFrameAllocSymbol( + GlobalValue::getRealLinkageName(Fn->getName()), IdxVal); // Create a TargetExternalSymbol for the label to avoid any target lowering // that would make this PC relative. diff --git a/lib/CodeGen/WinEHPrepare.cpp b/lib/CodeGen/WinEHPrepare.cpp index d12a8ed472b..9ebe8a2fc10 100644 --- a/lib/CodeGen/WinEHPrepare.cpp +++ b/lib/CodeGen/WinEHPrepare.cpp @@ -1595,7 +1595,7 @@ CleanupHandler *WinEHPrepare::findCleanupHandler(BasicBlock *StartBB, // This is a public function, declared in WinEHFuncInfo.h and is also // referenced by WinEHNumbering in FunctionLoweringInfo.cpp. void llvm::parseEHActions(const IntrinsicInst *II, - SmallVectorImpl &Actions) { + SmallVectorImpl &Actions) { for (unsigned I = 0, E = II->getNumArgOperands(); I != E;) { uint64_t ActionKind = cast(II->getArgOperand(I))->getZExtValue(); @@ -1609,14 +1609,14 @@ void llvm::parseEHActions(const IntrinsicInst *II, CH->setHandlerBlockOrFunc(Handler); CH->setExceptionVarIndex(EHObjIndexVal); Actions.push_back(CH); - } - else { - assert(ActionKind == 0 && "expected a cleanup or a catch action!"); + } else if (ActionKind == 0) { Constant *Handler = cast(II->getArgOperand(I + 1)); I += 2; auto *CH = new CleanupHandler(/*BB=*/nullptr); CH->setHandlerBlockOrFunc(Handler); Actions.push_back(CH); + } else { + llvm_unreachable("Expected either a catch or cleanup handler!"); } } std::reverse(Actions.begin(), Actions.end()); diff --git a/test/CodeGen/WinEH/cppeh-prepared-catch.ll b/test/CodeGen/WinEH/cppeh-prepared-catch.ll index 3bc864833e1..937b216edbd 100644 --- a/test/CodeGen/WinEH/cppeh-prepared-catch.ll +++ b/test/CodeGen/WinEH/cppeh-prepared-catch.ll @@ -148,13 +148,13 @@ try.cont8: ; preds = %lpad2, %try.cont ; CHECK-NEXT:"$handlerMap$0$?f@@YAXXZ": ; CHECK-NEXT: .long 8 ; CHECK-NEXT: .long "??_R0H@8"@IMGREL -; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long ".L?f@@YAXXZ$frame_escape_0" ; CHECK-NEXT: .long "?f@@YAXXZ.catch"@IMGREL ; CHECK-NEXT: .long ".L?f@@YAXXZ.catch$parent_frame_offset" ; CHECK-NEXT:"$handlerMap$1$?f@@YAXXZ": ; CHECK-NEXT: .long 0 ; CHECK-NEXT: .long "??_R0N@8"@IMGREL -; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long ".L?f@@YAXXZ$frame_escape_1" ; CHECK-NEXT: .long "?f@@YAXXZ.catch1"@IMGREL ; CHECK-NEXT: .long ".L?f@@YAXXZ.catch1$parent_frame_offset" ; CHECK-NEXT:"$ip2state$?f@@YAXXZ":