brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.8 KiB · 779e0be Raw
342 lines · c
1// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s2 3void g(void);4 5//////////////////////////////////////////////////////////////////////////////6// __leave with __except7 8// Nothing in the __try block can trap, so __try.cont isn't created.9int __leave_with___except_simple(void) {10  int myres = 0;11  __try {12    myres = 15;13    __leave;14    myres = 23;15  } __except (1) {16    return 0;17  }18  return 1;19}20// CHECK-LABEL: define dso_local i32 @__leave_with___except_simple()21// CHECK: store i32 15, ptr %myres22// CHECK-NEXT: br label %[[tryleave:[^ ]*]]23// CHECK-NOT: store i32 2324// CHECK: [[tryleave]]25// CHECK-NEXT: ret i32 126 27 28// The "normal" case.29int __leave_with___except(void) {30  int myres = 0;31  __try {32    g();33    __leave;34    myres = 23;35  } __except (1) {36    return 0;37  }38  return 1;39}40// CHECK-LABEL: define dso_local i32 @__leave_with___except()41// CHECK: invoke void @g()42// CHECK-NEXT:       to label %[[cont:.*]] unwind label %{{.*}}43// For __excepts, instead of an explicit __try.__leave label, we could use44// use invoke.cont as __leave jump target instead.  However, not doing this45// keeps the CodeGen code simpler, __leave is very rare, and SimplifyCFG will46// simplify this anyways.47// CHECK: [[cont]]48// CHECK-NEXT: br label %[[tryleave:[^ ]*]]49// CHECK-NOT: store i32 2350// CHECK: [[tryleave]]51// CHECK-NEXT: br label %52 53 54//////////////////////////////////////////////////////////////////////////////55// __leave with __finally56 57void abort(void) __attribute__((noreturn));58 59// Nothing in the __try block can trap, so __finally.cont and friends aren't60// created.61int __leave_with___finally_simple(void) {62  int myres = 0;63  __try {64    myres = 15;65    __leave;66    myres = 23;67  } __finally {68    return 0;69  }70  return 1;71}72// CHECK-LABEL: define dso_local i32 @__leave_with___finally_simple()73// CHECK: store i32 15, ptr %myres74// CHECK-NEXT: br label %[[tryleave:[^ ]*]]75// CHECK-NOT: store i32 2376// CHECK: [[tryleave]]77// CHECK-NEXT: %[[fp:[^ ]*]] = call ptr @llvm.localaddress()78// CHECK-NEXT: call void @"?fin$0@0@__leave_with___finally_simple@@"(i8 noundef 0, ptr noundef %[[fp]])79 80// __finally block doesn't return, __finally.cont doesn't exist.81int __leave_with___finally_noreturn(void) {82  int myres = 0;83  __try {84    myres = 15;85    __leave;86    myres = 23;87  } __finally {88    abort();89  }90  return 1;91}92// CHECK-LABEL: define dso_local i32 @__leave_with___finally_noreturn()93// CHECK: store i32 15, ptr %myres94// CHECK-NEXT: br label %[[tryleave:[^ ]*]]95// CHECK-NOT: store i32 2396// CHECK: [[tryleave]]97// CHECK-NEXT: %[[fp:[^ ]*]] = call ptr @llvm.localaddress()98// CHECK-NEXT: call void @"?fin$0@0@__leave_with___finally_noreturn@@"(i8 noundef 0, ptr noundef %[[fp]])99 100// The "normal" case.101int __leave_with___finally(void) {102  int myres = 0;103  __try {104    g();105    __leave;106    myres = 23;107  } __finally {108    return 0;109  }110  return 1;111}112// CHECK-LABEL: define dso_local i32 @__leave_with___finally()113// CHECK: invoke void @g()114// CHECK-NEXT:       to label %[[cont:.*]] unwind label %{{.*}}115// For __finally, there needs to be an explicit __try.__leave, because116// abnormal.termination.slot needs to be set there.117// CHECK: [[cont]]118// CHECK-NEXT: br label %[[tryleave:[^ ]*]]119// CHECK-NOT: store i32 23120// CHECK: [[tryleave]]121// CHECK-NEXT: %[[fp:[^ ]*]] = call ptr @llvm.localaddress()122// CHECK-NEXT: call void @"?fin$0@0@__leave_with___finally@@"(i8 noundef 0, ptr noundef %[[fp]])123 124 125//////////////////////////////////////////////////////////////////////////////126// Mixed, nested cases.127 128int nested___except___finally(void) {129  int myres = 0;130  __try {131    __try {132      g();133    } __finally {134      g();135      __leave;  // Refers to the outer __try, not the __finally!136      myres = 23;137      return 0;138    }139 140    myres = 51;141  } __except (1) {142  }143  return 1;144}145// CHECK-LABEL: define dso_local i32 @nested___except___finally()146 147// CHECK-LABEL: invoke void @g()148// CHECK-NEXT:       to label %[[g1_cont1:.*]] unwind label %[[g1_lpad:.*]]149 150// CHECK: [[g1_cont1]]151// CHECK-NEXT: %[[fp:[^ ]*]] = call ptr @llvm.localaddress()152// CHECK-NEXT: invoke void @"?fin$0@0@nested___except___finally@@"(i8 noundef 0, ptr noundef %[[fp]])153// CHECK-NEXT:       to label %[[fin_cont:.*]] unwind label %[[g2_lpad:.*]]154 155// CHECK: [[fin_cont]]156// CHECK: store i32 51, ptr %157// CHECK-NEXT: br label %[[trycont:[^ ]*]]158 159// CHECK: [[g1_lpad]]160// CHECK-NEXT: cleanuppad161// CHECK-NEXT: %[[fp:[^ ]*]] = call ptr @llvm.localaddress()162// CHECK-NEXT: invoke void @"?fin$0@0@nested___except___finally@@"(i8 noundef 1, ptr noundef %[[fp]])163// CHECK-NEXT:       to label %[[g1_resume:.*]] unwind label %[[g2_lpad]]164// CHECK: cleanupret {{.*}} unwind label %[[g2_lpad]]165 166// CHECK: [[g2_lpad]]167// CHECK: catchpad {{.*}} [ptr null]168// CHECK: catchret169// CHECK: br label %[[trycont]]170 171// CHECK: [[trycont]]172// CHECK-NEXT: ret i32 1173 174// CHECK-LABEL: define internal void @"?fin$0@0@nested___except___finally@@"(i8 noundef %abnormal_termination, ptr noundef %frame_pointer)175// CHECK: call void @g()176// CHECK: unreachable177 178int nested___except___except(void) {179  int myres = 0;180  __try {181    __try {182      g();183      myres = 16;184    } __except (1) {185      g();186      __leave;  // Refers to the outer __try, not the __except we're in!187      myres = 23;188      return 0;189    }190 191    myres = 51;192  } __except (1) {193  }194  return 1;195}196// The order of basic blocks in the below doesn't matter.197// CHECK-LABEL: define dso_local i32 @nested___except___except()198 199// CHECK-LABEL: invoke void @g()200// CHECK-NEXT:       to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]]201 202// CHECK: [[g1_lpad]]203// CHECK: catchpad {{.*}} [ptr null]204// CHECK: catchret {{.*}} to label %[[except:[^ ]*]]205// CHECK: [[except]]206// CHECK: invoke void @g()207// CHECK-NEXT:       to label %[[g2_cont:.*]] unwind label %[[g2_lpad:.*]]208 209// CHECK: [[g2_lpad]]210// CHECK: catchpad {{.*}} [ptr null]211// CHECK: catchret212// CHECK: br label %[[trycont4:[^ ]*]]213 214// CHECK: [[trycont4]]215// CHECK-NEXT: ret i32 1216 217// CHECK: [[g2_cont]]218// CHECK-NEXT: br label %[[tryleave:[^ ]*]]219// CHECK-NOT: store i32 23220 221// CHECK: [[g1_cont]]222// CHECK: store i32 16, ptr %myres223// CHECK-NEXT: br label %[[trycont:[^ ]*]]224 225// CHECK: [[trycont]]226// CHECK-NEXT: store i32 51, ptr %myres227// CHECK-NEXT: br label %[[tryleave]]228 229// CHECK: [[tryleave]]230// CHECK-NEXT: br label %[[trycont4]]231 232int nested___finally___except(void) {233  int myres = 0;234  __try {235    __try {236      g();237    } __except (1) {238      g();239      __leave;  // Refers to the outer __try, not the __except!240      myres = 23;241      return 0;242    }243 244    myres = 51;245  } __finally {246  }247  return 1;248}249// The order of basic blocks in the below doesn't matter.250// CHECK-LABEL: define dso_local i32 @nested___finally___except()251 252// CHECK-LABEL: invoke void @g()253// CHECK-NEXT:       to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]]254 255// CHECK: [[g1_lpad]]256// CHECK: catchpad257// CHECK: catchret258// CHECK: invoke void @g()259// CHECK-NEXT:       to label %[[g2_cont:.*]] unwind label %[[g2_lpad:.*]]260 261// CHECK: [[g2_cont]]262// CHECK: br label %[[tryleave:[^ ]*]]263// CHECK-NOT: 23264 265// CHECK: [[g1_cont]]266// CHECK-NEXT: br label %[[trycont:[^ ]*]]267 268// CHECK: [[trycont]]269// CHECK: store i32 51, ptr %270// CHECK-NEXT: br label %[[tryleave]]271 272// CHECK: [[tryleave]]273// CHECK: %[[fp:[^ ]*]] = call ptr @llvm.localaddress()274// CHECK-NEXT: call void @"?fin$0@0@nested___finally___except@@"(i8 noundef 0, ptr noundef %[[fp]])275// CHECK-NEXT: ret i32 1276 277// CHECK: [[g2_lpad]]278// CHECK: cleanuppad279// CHECK: %[[fp:[^ ]*]] = call ptr @llvm.localaddress()280// CHECK-NEXT: call void @"?fin$0@0@nested___finally___except@@"(i8 noundef 1, ptr noundef %[[fp]])281// CHECK: cleanupret {{.*}} unwind to caller282 283// CHECK-LABEL: define internal void @"?fin$0@0@nested___finally___except@@"(i8 noundef %abnormal_termination, ptr noundef %frame_pointer)284// CHECK: ret void285 286int nested___finally___finally(void) {287  int myres = 0;288  __try {289    __try {290      g();291      myres = 16;292    } __finally {293      g();294      __leave;  // Refers to the outer __try, not the __finally we're in!295      myres = 23;296      return 0;297    }298 299    myres = 51;300  } __finally {301  }302  return 1;303}304// The order of basic blocks in the below doesn't matter.305// CHECK-LABEL: define dso_local i32 @nested___finally___finally()306 307// CHECK: invoke void @g()308// CHECK-NEXT:       to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]]309 310// CHECK: [[g1_cont]]311// CHECK: store i32 16, ptr %[[myres:[^ ]*]],312// CHECK: %[[fp:[^ ]*]] = call ptr @llvm.localaddress()313// CHECK-NEXT: invoke void @"?fin$1@0@nested___finally___finally@@"(i8 noundef 0, ptr noundef %[[fp]])314// CHECK-NEXT:       to label %[[finally_cont:.*]] unwind label %[[g2_lpad:.*]]315 316// CHECK: [[finally_cont]]317// CHECK: store i32 51, ptr %[[myres]]318// CHECK: %[[fp:[^ ]*]] = call ptr @llvm.localaddress()319// CHECK-NEXT: call void @"?fin$0@0@nested___finally___finally@@"(i8 noundef 0, ptr noundef %[[fp]])320// CHECK-NEXT: ret i32 1321 322// CHECK: [[g1_lpad]]323// CHECK-NEXT: %[[padtoken:[^ ]*]] = cleanuppad within none []324// CHECK-NEXT: %[[fp:[^ ]*]] = call ptr @llvm.localaddress()325// CHECK-NEXT: invoke void @"?fin$1@0@nested___finally___finally@@"(i8 noundef 1, ptr noundef %[[fp]])326// CHECK-NEXT:       to label %[[finally_cont2:.*]] unwind label %[[g2_lpad]]327// CHECK: [[finally_cont2]]328// CHECK: cleanupret from %[[padtoken]] unwind label %[[g2_lpad]]329 330// CHECK: [[g2_lpad]]331// CHECK-NEXT: %[[padtoken:[^ ]*]] = cleanuppad within none []332// CHECK-NEXT: %[[fp:[^ ]*]] = call ptr @llvm.localaddress()333// CHECK-NEXT: call void @"?fin$0@0@nested___finally___finally@@"(i8 noundef 1, ptr noundef %[[fp]])334// CHECK: cleanupret from %[[padtoken]] unwind to caller335 336// CHECK-LABEL: define internal void @"?fin$0@0@nested___finally___finally@@"(i8 noundef %abnormal_termination, ptr noundef %frame_pointer)337// CHECK: ret void338 339// CHECK-LABEL: define internal void @"?fin$1@0@nested___finally___finally@@"(i8 noundef %abnormal_termination, ptr noundef %frame_pointer)340// CHECK: call void @g()341// CHECK: unreachable342