diff options
Diffstat (limited to 'clang/test')
-rw-r--r-- | clang/test/CodeGen/exceptions-seh-finally.c | 99 | ||||
-rw-r--r-- | clang/test/CodeGen/exceptions-seh.c | 11 | ||||
-rw-r--r-- | clang/test/Sema/__try.c | 2 |
3 files changed, 99 insertions, 13 deletions
diff --git a/clang/test/CodeGen/exceptions-seh-finally.c b/clang/test/CodeGen/exceptions-seh-finally.c index c8bf237f5a0..1eca72ae15c 100644 --- a/clang/test/CodeGen/exceptions-seh-finally.c +++ b/clang/test/CodeGen/exceptions-seh-finally.c @@ -13,19 +13,44 @@ void basic_finally(void) { // 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: landingpad +// CHECK: [[finallycont]] +// CHECK-NEXT: ret void +// +// CHECK: [[lpad]] +// CHECK-NEXT: landingpad // CHECK-NEXT: cleanup -// CHECK: invoke void @cleanup() +// CHECK: store i8 1, i8* %[[abnormal]] +// CHECK: br label %[[finally]] +// +// CHECK: [[resumecont]] +// CHECK: br label %[[ehresume:[^ ]*]] // -// CHECK: landingpad -// CHECK-NEXT: catch i8* null -// CHECK: call void @abort() +// CHECK: [[ehresume]] +// CHECK: resume { i8*, i32 } -// FIXME: This crashes. -#if 0 -void basic_finally(void) { +// 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 { @@ -35,4 +60,60 @@ l: goto l; } } -#endif + +// 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 } diff --git a/clang/test/CodeGen/exceptions-seh.c b/clang/test/CodeGen/exceptions-seh.c index 07b43c6f108..fcd90b99132 100644 --- a/clang/test/CodeGen/exceptions-seh.c +++ b/clang/test/CodeGen/exceptions-seh.c @@ -138,17 +138,22 @@ void basic_finally(void) { // CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] // // CHECK: [[cont]] +// CHECK: br label %[[finally:[^ ]*]] +// +// CHECK: [[finally]] // CHECK: load i32* @g // CHECK: add i32 %{{.*}}, -1 // CHECK: store i32 %{{.*}}, i32* @g +// CHECK: icmp eq +// CHECK: br i1 %{{.*}}, label +// // CHECK: ret void // // CHECK: [[lpad]] // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) // CHECK-NEXT: cleanup -// CHECK: load i32* @g -// CHECK: add i32 %{{.*}}, -1 -// CHECK: store i32 %{{.*}}, i32* @g +// CHECK: br label %[[finally]] +// // CHECK: resume int returns_int(void); diff --git a/clang/test/Sema/__try.c b/clang/test/Sema/__try.c index 607da9df27e..0e5de2018db 100644 --- a/clang/test/Sema/__try.c +++ b/clang/test/Sema/__try.c @@ -15,7 +15,7 @@ unsigned long __exception_code(); #ifdef BORLAND struct EXCEPTION_INFO* __exception_info(); #endif -void __abnormal_termination(); +int __abnormal_termination(); #define GetExceptionCode __exception_code #define GetExceptionInformation __exception_info |