From: David Majnemer Date: Wed, 17 Feb 2016 18:41:08 +0000 (+0000) Subject: Merging r260733: X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=fde3338c42eb085f169ecc3817c4736075e4a683 Merging r260733: ------------------------------------------------------------------------ r260733 | akaylor | 2016-02-12 13:10:16 -0800 (Fri, 12 Feb 2016) | 5 lines [WinEH] Prevent EH state numbering from skipping nested cleanup pads that never return Differential Revision: http://reviews.llvm.org/D17208 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_38@261124 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/WinEHPrepare.cpp b/lib/CodeGen/WinEHPrepare.cpp index 886c5f6070c..14ec9115980 100644 --- a/lib/CodeGen/WinEHPrepare.cpp +++ b/lib/CodeGen/WinEHPrepare.cpp @@ -257,10 +257,14 @@ static void calculateCXXStateNumbers(WinEHFuncInfo &FuncInfo, if (auto *InnerCatchSwitch = dyn_cast(UserI)) if (InnerCatchSwitch->getUnwindDest() == CatchSwitch->getUnwindDest()) calculateCXXStateNumbers(FuncInfo, UserI, CatchLow); - if (auto *InnerCleanupPad = dyn_cast(UserI)) - if (getCleanupRetUnwindDest(InnerCleanupPad) == - CatchSwitch->getUnwindDest()) + if (auto *InnerCleanupPad = dyn_cast(UserI)) { + BasicBlock *UnwindDest = getCleanupRetUnwindDest(InnerCleanupPad); + // If a nested cleanup pad reports a null unwind destination and the + // enclosing catch pad doesn't it must be post-dominated by an + // unreachable instruction. + if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest()) calculateCXXStateNumbers(FuncInfo, UserI, CatchLow); + } } } int CatchHigh = FuncInfo.getLastStateNumber(); @@ -360,10 +364,14 @@ static void calculateSEHStateNumbers(WinEHFuncInfo &FuncInfo, if (auto *InnerCatchSwitch = dyn_cast(UserI)) if (InnerCatchSwitch->getUnwindDest() == CatchSwitch->getUnwindDest()) calculateSEHStateNumbers(FuncInfo, UserI, ParentState); - if (auto *InnerCleanupPad = dyn_cast(UserI)) - if (getCleanupRetUnwindDest(InnerCleanupPad) == - CatchSwitch->getUnwindDest()) + if (auto *InnerCleanupPad = dyn_cast(UserI)) { + BasicBlock *UnwindDest = getCleanupRetUnwindDest(InnerCleanupPad); + // If a nested cleanup pad reports a null unwind destination and the + // enclosing catch pad doesn't it must be post-dominated by an + // unreachable instruction. + if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest()) calculateSEHStateNumbers(FuncInfo, UserI, ParentState); + } } } else { auto *CleanupPad = cast(FirstNonPHI); diff --git a/test/CodeGen/WinEH/wineh-noret-cleanup.ll b/test/CodeGen/WinEH/wineh-noret-cleanup.ll new file mode 100644 index 00000000000..7d4d833aa9b --- /dev/null +++ b/test/CodeGen/WinEH/wineh-noret-cleanup.ll @@ -0,0 +1,80 @@ +; RUN: sed -e s/.Cxx:// %s | llc -mtriple=x86_64-pc-windows-msvc | FileCheck %s --check-prefix=CXX +; RUN: sed -e s/.Seh:// %s | llc -mtriple=x86_64-pc-windows-msvc | FileCheck %s --check-prefix=SEH + +declare i32 @__CxxFrameHandler3(...) +declare i32 @__C_specific_handler(...) +declare void @dummy_filter() + +declare void @f(i32) + +;Cxx: define void @test() personality i32 (...)* @__CxxFrameHandler3 { +;Seh: define void @test() personality i32 (...)* @__C_specific_handler { +entry: + invoke void @f(i32 1) + to label %invoke.cont unwind label %catch.dispatch + +catch.dispatch: + %cs1 = catchswitch within none [label %catch.body] unwind label %catch.dispatch.2 + +catch.body: +;Cxx: %catch = catchpad within %cs1 [i8* null, i32 u0x40, i8* null] +;Seh: %catch = catchpad within %cs1 [void ()* @dummy_filter] + invoke void @f(i32 2) [ "funclet"(token %catch) ] + to label %unreachable unwind label %terminate + +terminate: + %cleanup = cleanuppad within %catch [] + call void @f(i32 3) [ "funclet"(token %cleanup) ] + unreachable + +unreachable: + unreachable + +invoke.cont: + ret void + +catch.dispatch.2: + %cs2 = catchswitch within none [label %catch.body.2] unwind to caller + +catch.body.2: +;Cxx: %catch2 = catchpad within %cs2 [i8* null, i32 u0x40, i8* null] +;Seh: %catch2 = catchpad within %cs2 [void ()* @dummy_filter] + unreachable +} + +; CXX-LABEL: test: +; CXX-LABEL: $ip2state$test: +; CXX-NEXT: .long .Lfunc_begin0@IMGREL +; CXX-NEXT: .long -1 +; CXX-NEXT: .long .Ltmp0@IMGREL+1 +; CXX-NEXT: .long 1 +; CXX-NEXT: .long .Ltmp1@IMGREL+1 +; CXX-NEXT: .long -1 +; CXX-NEXT: .long "?catch$3@?0?test@4HA"@IMGREL +; CXX-NEXT: .long 2 +; CXX-NEXT: .long .Ltmp2@IMGREL+1 +; CXX-NEXT: .long 3 +; CXX-NEXT: .long .Ltmp3@IMGREL+1 +; CXX-NEXT: .long 2 +; CXX-NEXT: .long "?catch$5@?0?test@4HA"@IMGREL +; CXX-NEXT: .long 4 + +; SEH-LABEL: test: +; SEH-LABEL: .Llsda_begin0: +; SEH-NEXT: .long .Ltmp0@IMGREL+1 +; SEH-NEXT: .long .Ltmp1@IMGREL+1 +; SEH-NEXT: .long dummy_filter@IMGREL +; SEH-NEXT: .long .LBB0_3@IMGREL +; SEH-NEXT: .long .Ltmp0@IMGREL+1 +; SEH-NEXT: .long .Ltmp1@IMGREL+1 +; SEH-NEXT: .long dummy_filter@IMGREL +; SEH-NEXT: .long .LBB0_5@IMGREL +; SEH-NEXT: .long .Ltmp2@IMGREL+1 +; SEH-NEXT: .long .Ltmp3@IMGREL+1 +; SEH-NEXT: .long "?dtor$2@?0?test@4HA"@IMGREL +; SEH-NEXT: .long 0 +; SEH-NEXT: .long .Ltmp2@IMGREL+1 +; SEH-NEXT: .long .Ltmp3@IMGREL+1 +; SEH-NEXT: .long dummy_filter@IMGREL +; SEH-NEXT: .long .LBB0_5@IMGREL +; SEH-NEXT: .Llsda_end0: