Author: Jennifer Yu Date: 2023-08-21T17:07:38-07:00 New Revision: ff08c8e57e39d7970b65637595cdc221901f4ed1
URL: https://github.com/llvm/llvm-project/commit/ff08c8e57e39d7970b65637595cdc221901f4ed1 DIFF: https://github.com/llvm/llvm-project/commit/ff08c8e57e39d7970b65637595cdc221901f4ed1.diff LOG: [SEH] Fix wrong argument passes to the call of OutlinedFinally. When return out of __try block. In this test case, currently "false" is passed to OutlinedFinally's call. "true" should be passed to indicate abnormal terminations. The rule: Except _leave and fall-through at the end, all other exits in a _try (return/goto/continue/break) are considered as abnormal terminations, NormalCleanupDestSlot is used to indicate abnormal terminations. The problem is, during the processing abnormal terminations, the ExitSwitch is used. However, in this case, Existswitch is route out. One way to fix is to skip route it without a switch. So proper abnormal termination's code could be generated. Differential Revision: https://reviews.llvm.org/D158233 Added: Modified: clang/lib/CodeGen/CGCleanup.cpp clang/test/CodeGen/exceptions-seh-finally.c clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp index cd51024a2b32d9..f87caf050eeaa7 100644 --- a/clang/lib/CodeGen/CGCleanup.cpp +++ b/clang/lib/CodeGen/CGCleanup.cpp @@ -873,8 +873,13 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { // If there's exactly one branch-after and no other threads, // we can route it without a switch. + // Skip for SEH, since ExitSwitch is used to generate code to indicate + // abnormal termination. (SEH: Except _leave and fall-through at + // the end, all other exits in a _try (return/goto/continue/break) + // are considered as abnormal terminations, using NormalCleanupDestSlot + // to indicate abnormal termination) if (!Scope.hasBranchThroughs() && !HasFixups && !HasFallthrough && - Scope.getNumBranchAfters() == 1) { + !currentFunctionUsesSEHTry() && Scope.getNumBranchAfters() == 1) { assert(!BranchThroughDest || !IsActive); // Clean up the possibly dead store to the cleanup dest slot. diff --git a/clang/test/CodeGen/exceptions-seh-finally.c b/clang/test/CodeGen/exceptions-seh-finally.c index 8ef5ca807b1d3b..0cdf2303112500 100644 --- a/clang/test/CodeGen/exceptions-seh-finally.c +++ b/clang/test/CodeGen/exceptions-seh-finally.c @@ -154,8 +154,11 @@ int finally_with_return(void) { } } // CHECK-LABEL: define dso_local i32 @finally_with_return() +// CHECK: store i32 1, ptr %cleanup.dest.slot +// CHECK: %cleanup.dest = load i32, ptr %cleanup.dest.slot +// CHECK: icmp ne i32 %cleanup.dest // CHECK: call void @"?fin$0@0@finally_with_return@@"({{.*}}) -// CHECK-NEXT: ret i32 42 +// CHECK: ret i32 42 // CHECK: define internal void @"?fin$0@0@finally_with_return@@"({{.*}}) // CHECK-SAME: [[finally_attrs]] diff --git a/clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp b/clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp index 4494e284b462c2..fab567e763df44 100644 --- a/clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp +++ b/clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -triple x86_64-windows -fasync-exceptions -fcxx-exceptions -fexceptions -fms-extensions -x c++ -Wno-implicit-function-declaration -S -emit-llvm %s -o - | FileCheck %s +// CHECK-LABEL: @main() // CHECK: invoke void @llvm.seh.try.begin() // CHECK: invoke void @llvm.seh.try.begin() // CHECK: %[[src:[0-9-]+]] = load volatile i32, ptr %i @@ -40,3 +41,29 @@ int main() { } return 0; } + +// CHECK-LABEL:@"?foo@@YAXXZ"() +// CHECK: invoke.cont: +// CHECK: invoke void @llvm.seh.try.begin() +// CHECK: store volatile i32 1, ptr %cleanup.dest.slot +// CHECK: invoke void @llvm.seh.try.end() +// CHECK: invoke.cont2: +// CHECK: %cleanup.dest = load i32, ptr %cleanup.dest.slot +// CHECK: %1 = icmp ne i32 %cleanup.dest, 0 +// CHECK: %2 = zext i1 %1 to i8 +// CHECK: call void @"?fin$0@0@foo@@"(i8 noundef %2, ptr noundef %0) +// CHECK: ehcleanup: +// CHECK: call void @"?fin$0@0@foo@@"(i8 noundef 1, ptr noundef %4) +void foo() +{ + __try { + return; + } + __finally { + if (_abnormal_termination()) { + printf("Passed\n"); + } else { + printf("Failed\n"); + } + } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits