Skip to content

Commit

Permalink
[SEH] Fix wrong argument passes to the call of OutlinedFinally.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
jyu2-git committed Aug 22, 2023
1 parent b58e528 commit ff08c8e
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 2 deletions.
7 changes: 6 additions & 1 deletion clang/lib/CodeGen/CGCleanup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
5 changes: 4 additions & 1 deletion clang/test/CodeGen/exceptions-seh-finally.c
Original file line number Diff line number Diff line change
Expand Up @@ -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]]
Expand Down
27 changes: 27 additions & 0 deletions clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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");
}
}
}

0 comments on commit ff08c8e

Please sign in to comment.