| // RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - | opt -instnamer -S | FileCheck %s | 
 |  | 
 | void g(void); | 
 |  | 
 | ////////////////////////////////////////////////////////////////////////////// | 
 | // __leave with __except | 
 |  | 
 | // Nothing in the __try block can trap, so __try.cont isn't created. | 
 | int __leave_with___except_simple() { | 
 |   int myres = 0; | 
 |   __try { | 
 |     myres = 15; | 
 |     __leave; | 
 |     myres = 23; | 
 |   } __except (1) { | 
 |     return 0; | 
 |   } | 
 |   return 1; | 
 | } | 
 | // CHECK-LABEL: define dso_local i32 @__leave_with___except_simple() | 
 | // CHECK: store i32 15, i32* %myres | 
 | // CHECK-NEXT: br label %[[tryleave:[^ ]*]] | 
 | // CHECK-NOT: store i32 23 | 
 | // CHECK: [[tryleave]] | 
 | // CHECK-NEXT: ret i32 1 | 
 |  | 
 |  | 
 | // The "normal" case. | 
 | int __leave_with___except() { | 
 |   int myres = 0; | 
 |   __try { | 
 |     g(); | 
 |     __leave; | 
 |     myres = 23; | 
 |   } __except (1) { | 
 |     return 0; | 
 |   } | 
 |   return 1; | 
 | } | 
 | // CHECK-LABEL: define dso_local i32 @__leave_with___except() | 
 | // CHECK: invoke void @g() | 
 | // CHECK-NEXT:       to label %[[cont:.*]] unwind label %{{.*}} | 
 | // For __excepts, instead of an explicit __try.__leave label, we could use | 
 | // use invoke.cont as __leave jump target instead.  However, not doing this | 
 | // keeps the CodeGen code simpler, __leave is very rare, and SimplifyCFG will | 
 | // simplify this anyways. | 
 | // CHECK: [[cont]] | 
 | // CHECK-NEXT: br label %[[tryleave:[^ ]*]] | 
 | // CHECK-NOT: store i32 23 | 
 | // CHECK: [[tryleave]] | 
 | // CHECK-NEXT: br label % | 
 |  | 
 |  | 
 | ////////////////////////////////////////////////////////////////////////////// | 
 | // __leave with __finally | 
 |  | 
 | void abort(void) __attribute__((noreturn)); | 
 |  | 
 | // Nothing in the __try block can trap, so __finally.cont and friends aren't | 
 | // created. | 
 | int __leave_with___finally_simple() { | 
 |   int myres = 0; | 
 |   __try { | 
 |     myres = 15; | 
 |     __leave; | 
 |     myres = 23; | 
 |   } __finally { | 
 |     return 0; | 
 |   } | 
 |   return 1; | 
 | } | 
 | // CHECK-LABEL: define dso_local i32 @__leave_with___finally_simple() | 
 | // CHECK: store i32 15, i32* %myres | 
 | // CHECK-NEXT: br label %[[tryleave:[^ ]*]] | 
 | // CHECK-NOT: store i32 23 | 
 | // CHECK: [[tryleave]] | 
 | // CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress() | 
 | // CHECK-NEXT: call void @"?fin$0@0@__leave_with___finally_simple@@"(i8 0, i8* %[[fp]]) | 
 |  | 
 | // __finally block doesn't return, __finally.cont doesn't exist. | 
 | int __leave_with___finally_noreturn() { | 
 |   int myres = 0; | 
 |   __try { | 
 |     myres = 15; | 
 |     __leave; | 
 |     myres = 23; | 
 |   } __finally { | 
 |     abort(); | 
 |   } | 
 |   return 1; | 
 | } | 
 | // CHECK-LABEL: define dso_local i32 @__leave_with___finally_noreturn() | 
 | // CHECK: store i32 15, i32* %myres | 
 | // CHECK-NEXT: br label %[[tryleave:[^ ]*]] | 
 | // CHECK-NOT: store i32 23 | 
 | // CHECK: [[tryleave]] | 
 | // CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress() | 
 | // CHECK-NEXT: call void @"?fin$0@0@__leave_with___finally_noreturn@@"(i8 0, i8* %[[fp]]) | 
 |  | 
 | // The "normal" case. | 
 | int __leave_with___finally() { | 
 |   int myres = 0; | 
 |   __try { | 
 |     g(); | 
 |     __leave; | 
 |     myres = 23; | 
 |   } __finally { | 
 |     return 0; | 
 |   } | 
 |   return 1; | 
 | } | 
 | // CHECK-LABEL: define dso_local i32 @__leave_with___finally() | 
 | // CHECK: invoke void @g() | 
 | // CHECK-NEXT:       to label %[[cont:.*]] unwind label %{{.*}} | 
 | // For __finally, there needs to be an explicit __try.__leave, because | 
 | // abnormal.termination.slot needs to be set there. | 
 | // CHECK: [[cont]] | 
 | // CHECK-NEXT: br label %[[tryleave:[^ ]*]] | 
 | // CHECK-NOT: store i32 23 | 
 | // CHECK: [[tryleave]] | 
 | // CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress() | 
 | // CHECK-NEXT: call void @"?fin$0@0@__leave_with___finally@@"(i8 0, i8* %[[fp]]) | 
 |  | 
 |  | 
 | ////////////////////////////////////////////////////////////////////////////// | 
 | // Mixed, nested cases. | 
 |  | 
 | int nested___except___finally() { | 
 |   int myres = 0; | 
 |   __try { | 
 |     __try { | 
 |       g(); | 
 |     } __finally { | 
 |       g(); | 
 |       __leave;  // Refers to the outer __try, not the __finally! | 
 |       myres = 23; | 
 |       return 0; | 
 |     } | 
 |  | 
 |     myres = 51; | 
 |   } __except (1) { | 
 |   } | 
 |   return 1; | 
 | } | 
 | // CHECK-LABEL: define dso_local i32 @nested___except___finally() | 
 |  | 
 | // CHECK-LABEL: invoke void @g() | 
 | // CHECK-NEXT:       to label %[[g1_cont1:.*]] unwind label %[[g1_lpad:.*]] | 
 |  | 
 | // CHECK: [[g1_cont1]] | 
 | // CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress() | 
 | // CHECK-NEXT: invoke void @"?fin$0@0@nested___except___finally@@"(i8 0, i8* %[[fp]]) | 
 | // CHECK-NEXT:       to label %[[fin_cont:.*]] unwind label %[[g2_lpad:.*]] | 
 |  | 
 | // CHECK: [[fin_cont]] | 
 | // CHECK: store i32 51, i32* % | 
 | // CHECK-NEXT: br label %[[trycont:[^ ]*]] | 
 |  | 
 | // CHECK: [[g1_lpad]] | 
 | // CHECK-NEXT: cleanuppad | 
 | // CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress() | 
 | // CHECK-NEXT: invoke void @"?fin$0@0@nested___except___finally@@"(i8 1, i8* %[[fp]]) | 
 | // CHECK-NEXT:       to label %[[g1_resume:.*]] unwind label %[[g2_lpad]] | 
 | // CHECK: cleanupret {{.*}} unwind label %[[g2_lpad]] | 
 |  | 
 | // CHECK: [[g2_lpad]] | 
 | // CHECK: catchpad {{.*}} [i8* null] | 
 | // CHECK: catchret | 
 | // CHECK: br label %[[trycont]] | 
 |  | 
 | // CHECK: [[trycont]] | 
 | // CHECK-NEXT: ret i32 1 | 
 |  | 
 | // CHECK-LABEL: define internal void @"?fin$0@0@nested___except___finally@@"(i8 %abnormal_termination, i8* %frame_pointer) | 
 | // CHECK: call void @g() | 
 | // CHECK: unreachable | 
 |  | 
 | int nested___except___except() { | 
 |   int myres = 0; | 
 |   __try { | 
 |     __try { | 
 |       g(); | 
 |       myres = 16; | 
 |     } __except (1) { | 
 |       g(); | 
 |       __leave;  // Refers to the outer __try, not the __except we're in! | 
 |       myres = 23; | 
 |       return 0; | 
 |     } | 
 |  | 
 |     myres = 51; | 
 |   } __except (1) { | 
 |   } | 
 |   return 1; | 
 | } | 
 | // The order of basic blocks in the below doesn't matter. | 
 | // CHECK-LABEL: define dso_local i32 @nested___except___except() | 
 |  | 
 | // CHECK-LABEL: invoke void @g() | 
 | // CHECK-NEXT:       to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]] | 
 |  | 
 | // CHECK: [[g1_lpad]] | 
 | // CHECK: catchpad {{.*}} [i8* null] | 
 | // CHECK: catchret {{.*}} to label %[[except:[^ ]*]] | 
 | // CHECK: [[except]] | 
 | // CHECK: invoke void @g() | 
 | // CHECK-NEXT:       to label %[[g2_cont:.*]] unwind label %[[g2_lpad:.*]] | 
 |  | 
 | // CHECK: [[g2_lpad]] | 
 | // CHECK: catchpad {{.*}} [i8* null] | 
 | // CHECK: catchret | 
 | // CHECK: br label %[[trycont4:[^ ]*]] | 
 |  | 
 | // CHECK: [[trycont4]] | 
 | // CHECK-NEXT: ret i32 1 | 
 |  | 
 | // CHECK: [[g2_cont]] | 
 | // CHECK-NEXT: br label %[[tryleave:[^ ]*]] | 
 | // CHECK-NOT: store i32 23 | 
 |  | 
 | // CHECK: [[g1_cont]] | 
 | // CHECK: store i32 16, i32* %myres | 
 | // CHECK-NEXT: br label %[[trycont:[^ ]*]] | 
 |  | 
 | // CHECK: [[trycont]] | 
 | // CHECK-NEXT: store i32 51, i32* %myres | 
 | // CHECK-NEXT: br label %[[tryleave]] | 
 |  | 
 | // CHECK: [[tryleave]] | 
 | // CHECK-NEXT: br label %[[trycont4]] | 
 |  | 
 | int nested___finally___except() { | 
 |   int myres = 0; | 
 |   __try { | 
 |     __try { | 
 |       g(); | 
 |     } __except (1) { | 
 |       g(); | 
 |       __leave;  // Refers to the outer __try, not the __except! | 
 |       myres = 23; | 
 |       return 0; | 
 |     } | 
 |  | 
 |     myres = 51; | 
 |   } __finally { | 
 |   } | 
 |   return 1; | 
 | } | 
 | // The order of basic blocks in the below doesn't matter. | 
 | // CHECK-LABEL: define dso_local i32 @nested___finally___except() | 
 |  | 
 | // CHECK-LABEL: invoke void @g() | 
 | // CHECK-NEXT:       to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]] | 
 |  | 
 | // CHECK: [[g1_lpad]] | 
 | // CHECK: catchpad | 
 | // CHECK: catchret | 
 | // CHECK: invoke void @g() | 
 | // CHECK-NEXT:       to label %[[g2_cont:.*]] unwind label %[[g2_lpad:.*]] | 
 |  | 
 | // CHECK: [[g2_cont]] | 
 | // CHECK: br label %[[tryleave:[^ ]*]] | 
 | // CHECK-NOT: 23 | 
 |  | 
 | // CHECK: [[g1_cont]] | 
 | // CHECK-NEXT: br label %[[trycont:[^ ]*]] | 
 |  | 
 | // CHECK: [[trycont]] | 
 | // CHECK: store i32 51, i32* % | 
 | // CHECK-NEXT: br label %[[tryleave]] | 
 |  | 
 | // CHECK: [[tryleave]] | 
 | // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress() | 
 | // CHECK-NEXT: call void @"?fin$0@0@nested___finally___except@@"(i8 0, i8* %[[fp]]) | 
 | // CHECK-NEXT: ret i32 1 | 
 |  | 
 | // CHECK: [[g2_lpad]] | 
 | // CHECK: cleanuppad | 
 | // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress() | 
 | // CHECK-NEXT: call void @"?fin$0@0@nested___finally___except@@"(i8 1, i8* %[[fp]]) | 
 | // CHECK: cleanupret {{.*}} unwind to caller | 
 |  | 
 | // CHECK-LABEL: define internal void @"?fin$0@0@nested___finally___except@@"(i8 %abnormal_termination, i8* %frame_pointer) | 
 | // CHECK: ret void | 
 |  | 
 | int nested___finally___finally() { | 
 |   int myres = 0; | 
 |   __try { | 
 |     __try { | 
 |       g(); | 
 |       myres = 16; | 
 |     } __finally { | 
 |       g(); | 
 |       __leave;  // Refers to the outer __try, not the __finally we're in! | 
 |       myres = 23; | 
 |       return 0; | 
 |     } | 
 |  | 
 |     myres = 51; | 
 |   } __finally { | 
 |   } | 
 |   return 1; | 
 | } | 
 | // The order of basic blocks in the below doesn't matter. | 
 | // CHECK-LABEL: define dso_local i32 @nested___finally___finally() | 
 |  | 
 | // CHECK: invoke void @g() | 
 | // CHECK-NEXT:       to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]] | 
 |  | 
 | // CHECK: [[g1_cont]] | 
 | // CHECK: store i32 16, i32* %[[myres:[^ ]*]], | 
 | // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress() | 
 | // CHECK-NEXT: invoke void @"?fin$1@0@nested___finally___finally@@"(i8 0, i8* %[[fp]]) | 
 | // CHECK-NEXT:       to label %[[finally_cont:.*]] unwind label %[[g2_lpad:.*]] | 
 |  | 
 | // CHECK: [[finally_cont]] | 
 | // CHECK: store i32 51, i32* %[[myres]] | 
 | // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress() | 
 | // CHECK-NEXT: call void @"?fin$0@0@nested___finally___finally@@"(i8 0, i8* %[[fp]]) | 
 | // CHECK-NEXT: ret i32 1 | 
 |  | 
 | // CHECK: [[g1_lpad]] | 
 | // CHECK-NEXT: %[[padtoken:[^ ]*]] = cleanuppad within none [] | 
 | // CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress() | 
 | // CHECK-NEXT: invoke void @"?fin$1@0@nested___finally___finally@@"(i8 1, i8* %[[fp]]) | 
 | // CHECK-NEXT:       to label %[[finally_cont2:.*]] unwind label %[[g2_lpad]] | 
 | // CHECK: [[finally_cont2]] | 
 | // CHECK: cleanupret from %[[padtoken]] unwind label %[[g2_lpad]] | 
 |  | 
 | // CHECK: [[g2_lpad]] | 
 | // CHECK-NEXT: %[[padtoken:[^ ]*]] = cleanuppad within none [] | 
 | // CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress() | 
 | // CHECK-NEXT: call void @"?fin$0@0@nested___finally___finally@@"(i8 1, i8* %[[fp]]) | 
 | // CHECK: cleanupret from %[[padtoken]] unwind to caller | 
 |  | 
 | // CHECK-LABEL: define internal void @"?fin$0@0@nested___finally___finally@@"(i8 %abnormal_termination, i8* %frame_pointer) | 
 | // CHECK: ret void | 
 |  | 
 | // CHECK-LABEL: define internal void @"?fin$1@0@nested___finally___finally@@"(i8 %abnormal_termination, i8* %frame_pointer) | 
 | // CHECK: call void @g() | 
 | // CHECK: unreachable |