diff --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp --- a/llvm/lib/CodeGen/WinEHPrepare.cpp +++ b/llvm/lib/CodeGen/WinEHPrepare.cpp @@ -155,11 +155,13 @@ HT.TypeDescriptor = cast(TypeInfo->stripPointerCasts()); HT.Adjectives = cast(CPI->getArgOperand(1))->getZExtValue(); HT.Handler = CPI->getParent(); - if (auto *AI = - dyn_cast(CPI->getArgOperand(2)->stripPointerCasts())) + HT.CatchObj.Alloca = nullptr; + Value *V = CPI->getArgOperand(2)->stripPointerCasts(); + auto *AI = dyn_cast(V); + assert((AI || isa(V)) && "must be alloc or null ptr"); + // Silently ignore dynamic allocas. + if (AI && AI->isStaticAlloca()) HT.CatchObj.Alloca = AI; - else - HT.CatchObj.Alloca = nullptr; TBME.HandlerArray.push_back(HT); } FuncInfo.TryBlockMap.push_back(TBME); diff --git a/llvm/test/CodeGen/X86/win-catchpad.ll b/llvm/test/CodeGen/X86/win-catchpad.ll --- a/llvm/test/CodeGen/X86/win-catchpad.ll +++ b/llvm/test/CodeGen/X86/win-catchpad.ll @@ -353,3 +353,37 @@ ; X64-NEXT: .long -1 ; X64-NEXT: .long "?catch$[[catchbb]]@?0?branch_to_normal_dest@4HA"@IMGREL ; X64-NEXT: .long 1 + +%struct.widget = type { i8**, i8*, [8 x i8] } + +@global = external global %struct.widget + +;; Check no crash if catch object is a dynamic alloca. +define dso_local void @baz() local_unnamed_addr #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { +bb: + br i1 poison, label %bb1, label %bb7 + +bb1: ; preds = %bb + %tmp = alloca i32, align 4 + invoke void @foo() + to label %bb6 unwind label %bb2 + +bb2: ; preds = %bb1 + %tmp3 = catchswitch within none [label %bb4] unwind label %bb8 + +bb4: ; preds = %bb2 + %tmp5 = catchpad within %tmp3 [%struct.widget* @global, i32 0, i32* %tmp] + unreachable + +bb6: ; preds = %bb1 + unreachable + +bb7: ; preds = %bb + ret void + +bb8: ; preds = %bb2 + %tmp9 = cleanuppad within none [] + unreachable +} + +declare dso_local void @foo() local_unnamed_addr