forked from OSchip/llvm-project
163 lines
3.7 KiB
C
163 lines
3.7 KiB
C
// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
|
|
|
|
void abort(void) __attribute__((noreturn));
|
|
void might_crash(void);
|
|
void cleanup(void);
|
|
int check_condition(void);
|
|
void basic_finally(void) {
|
|
__try {
|
|
might_crash();
|
|
} __finally {
|
|
cleanup();
|
|
}
|
|
}
|
|
|
|
// CHECK-LABEL: define void @basic_finally()
|
|
// CHECK: invoke void @might_crash()
|
|
// CHECK: to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
|
|
//
|
|
// CHECK: [[invoke_cont]]
|
|
// CHECK: store i8 0, i8* %[[abnormal:[^ ]*]]
|
|
// CHECK: br label %[[finally:[^ ]*]]
|
|
//
|
|
// CHECK: [[finally]]
|
|
// CHECK: call void @cleanup()
|
|
// CHECK: load i8* %[[abnormal]]
|
|
// CHECK: icmp eq
|
|
// CHECK: br i1 %{{.*}}, label %[[finallycont:[^ ]*]], label %[[resumecont:[^ ]*]]
|
|
//
|
|
// CHECK: [[finallycont]]
|
|
// CHECK-NEXT: ret void
|
|
//
|
|
// CHECK: [[lpad]]
|
|
// CHECK-NEXT: landingpad
|
|
// CHECK-NEXT: cleanup
|
|
// CHECK: store i8 1, i8* %[[abnormal]]
|
|
// CHECK: br label %[[finally]]
|
|
//
|
|
// CHECK: [[resumecont]]
|
|
// CHECK: br label %[[ehresume:[^ ]*]]
|
|
//
|
|
// CHECK: [[ehresume]]
|
|
// CHECK: resume { i8*, i32 }
|
|
|
|
// Mostly check that we don't double emit 'r' which would crash.
|
|
void decl_in_finally(void) {
|
|
__try {
|
|
might_crash();
|
|
} __finally {
|
|
int r;
|
|
}
|
|
}
|
|
|
|
// Ditto, don't crash double emitting 'l'.
|
|
void label_in_finally(void) {
|
|
__try {
|
|
might_crash();
|
|
} __finally {
|
|
l:
|
|
cleanup();
|
|
if (check_condition())
|
|
goto l;
|
|
}
|
|
}
|
|
|
|
// CHECK-LABEL: define void @label_in_finally()
|
|
// CHECK: invoke void @might_crash()
|
|
// CHECK: to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
|
|
//
|
|
// CHECK: [[invoke_cont]]
|
|
// CHECK: store i8 0, i8* %[[abnormal:[^ ]*]]
|
|
// CHECK: br label %[[finally:[^ ]*]]
|
|
//
|
|
// CHECK: [[finally]]
|
|
// CHECK: br label %[[l:[^ ]*]]
|
|
//
|
|
// CHECK: [[l]]
|
|
// CHECK: call void @cleanup()
|
|
// CHECK: call i32 @check_condition()
|
|
// CHECK: br i1 {{.*}}, label
|
|
// CHECK: br label %[[l]]
|
|
|
|
int crashed;
|
|
void use_abnormal_termination(void) {
|
|
__try {
|
|
might_crash();
|
|
} __finally {
|
|
crashed = __abnormal_termination();
|
|
}
|
|
}
|
|
|
|
// CHECK-LABEL: define void @use_abnormal_termination()
|
|
// CHECK: invoke void @might_crash()
|
|
// CHECK: to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
|
|
//
|
|
// CHECK: [[invoke_cont]]
|
|
// CHECK: store i8 0, i8* %[[abnormal:[^ ]*]]
|
|
// CHECK: br label %[[finally:[^ ]*]]
|
|
//
|
|
// CHECK: [[finally]]
|
|
// CHECK: load i8* %[[abnormal]]
|
|
// CHECK: zext i8 %{{.*}} to i32
|
|
// CHECK: store i32 %{{.*}}, i32* @crashed
|
|
// CHECK: load i8* %[[abnormal]]
|
|
// CHECK: icmp eq
|
|
// CHECK: br i1 %{{.*}}, label %[[finallycont:[^ ]*]], label %[[resumecont:[^ ]*]]
|
|
//
|
|
// CHECK: [[finallycont]]
|
|
// CHECK-NEXT: ret void
|
|
//
|
|
// CHECK: [[lpad]]
|
|
// CHECK-NEXT: landingpad
|
|
// CHECK-NEXT: cleanup
|
|
// CHECK: store i8 1, i8* %[[abnormal]]
|
|
// CHECK: br label %[[finally]]
|
|
//
|
|
// CHECK: [[resumecont]]
|
|
// CHECK: br label %[[ehresume:[^ ]*]]
|
|
//
|
|
// CHECK: [[ehresume]]
|
|
// CHECK: resume { i8*, i32 }
|
|
|
|
void noreturn_noop_finally() {
|
|
__try {
|
|
__noop();
|
|
} __finally {
|
|
abort();
|
|
}
|
|
}
|
|
|
|
// CHECK-LABEL: define void @noreturn_noop_finally()
|
|
// CHECK: store i8 0, i8* %
|
|
// CHECK: br label %[[finally:[^ ]*]]
|
|
// CHECK: [[finally]]
|
|
// CHECK: call void @abort()
|
|
// CHECK-NEXT: unreachable
|
|
// CHECK-NOT: load
|
|
|
|
void noreturn_finally() {
|
|
__try {
|
|
might_crash();
|
|
} __finally {
|
|
abort();
|
|
}
|
|
}
|
|
|
|
// CHECK-LABEL: define void @noreturn_finally()
|
|
// CHECK: invoke void @might_crash()
|
|
// CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
|
|
//
|
|
// CHECK: [[cont]]
|
|
// CHECK: store i8 0, i8* %
|
|
// CHECK: br label %[[finally:[^ ]*]]
|
|
//
|
|
// CHECK: [[finally]]
|
|
// CHECK: call void @abort()
|
|
// CHECK-NEXT: unreachable
|
|
//
|
|
// CHECK: [[lpad]]
|
|
// CHECK: landingpad
|
|
// CHECK-NEXT: cleanup
|
|
// CHECK: store i8 1, i8* %
|
|
// CHECK: br label %[[finally]]
|