Home | History | Annotate | Download | only in CodeGen
      1 // RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - | opt -instnamer -S | FileCheck %s
      2 
      3 void g(void);
      4 
      5 //////////////////////////////////////////////////////////////////////////////
      6 // __leave with __except
      7 
      8 // Nothing in the __try block can trap, so __try.cont isn't created.
      9 int __leave_with___except_simple() {
     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 i32 @__leave_with___except_simple()
     21 // CHECK: store i32 15, i32* %myres
     22 // CHECK-NEXT: br label %[[tryleave:[^ ]*]]
     23 // CHECK-NOT: store i32 23
     24 // CHECK: [[tryleave]]
     25 // CHECK-NEXT: ret i32 1
     26 
     27 
     28 // The "normal" case.
     29 int __leave_with___except() {
     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 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 use
     44 // use invoke.cont as __leave jump target instead.  However, not doing this
     45 // keeps the CodeGen code simpler, __leave is very rare, and SimplifyCFG will
     46 // simplify this anyways.
     47 // CHECK: [[cont]]
     48 // CHECK-NEXT: br label %[[tryleave:[^ ]*]]
     49 // CHECK-NOT: store i32 23
     50 // CHECK: [[tryleave]]
     51 // CHECK-NEXT: br label %
     52 
     53 
     54 //////////////////////////////////////////////////////////////////////////////
     55 // __leave with __finally
     56 
     57 void abort(void) __attribute__((noreturn));
     58 
     59 // Nothing in the __try block can trap, so __finally.cont and friends aren't
     60 // created.
     61 int __leave_with___finally_simple() {
     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 i32 @__leave_with___finally_simple()
     73 // CHECK: store i32 15, i32* %myres
     74 // CHECK-NEXT: br label %[[tryleave:[^ ]*]]
     75 // CHECK-NOT: store i32 23
     76 // CHECK: [[tryleave]]
     77 // CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
     78 // CHECK-NEXT: call void @"\01?fin$0@0@__leave_with___finally_simple@@"(i8 0, i8* %[[fp]])
     79 
     80 // __finally block doesn't return, __finally.cont doesn't exist.
     81 int __leave_with___finally_noreturn() {
     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 i32 @__leave_with___finally_noreturn()
     93 // CHECK: store i32 15, i32* %myres
     94 // CHECK-NEXT: br label %[[tryleave:[^ ]*]]
     95 // CHECK-NOT: store i32 23
     96 // CHECK: [[tryleave]]
     97 // CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
     98 // CHECK-NEXT: call void @"\01?fin$0@0@__leave_with___finally_noreturn@@"(i8 0, i8* %[[fp]])
     99 
    100 // The "normal" case.
    101 int __leave_with___finally() {
    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 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, because
    116 // abnormal.termination.slot needs to be set there.
    117 // CHECK: [[cont]]
    118 // CHECK-NEXT: br label %[[tryleave:[^ ]*]]
    119 // CHECK-NOT: store i32 23
    120 // CHECK: [[tryleave]]
    121 // CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
    122 // CHECK-NEXT: call void @"\01?fin$0@0@__leave_with___finally@@"(i8 0, i8* %[[fp]])
    123 
    124 
    125 //////////////////////////////////////////////////////////////////////////////
    126 // Mixed, nested cases.
    127 
    128 int nested___except___finally() {
    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 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 i8* @llvm.localaddress()
    152 // CHECK-NEXT: invoke void @"\01?fin$0@0@nested___except___finally@@"(i8 0, i8* %[[fp]])
    153 // CHECK-NEXT:       to label %[[fin_cont:.*]] unwind label %[[g2_lpad:.*]]
    154 
    155 // CHECK: [[fin_cont]]
    156 // CHECK: store i32 51, i32* %
    157 // CHECK-NEXT: br label %[[trycont:[^ ]*]]
    158 
    159 // CHECK: [[g1_lpad]]
    160 // CHECK-NEXT: cleanuppad
    161 // CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
    162 // CHECK-NEXT: invoke void @"\01?fin$0@0@nested___except___finally@@"(i8 1, i8* %[[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 {{.*}} [i8* null]
    168 // CHECK: catchret
    169 // CHECK: br label %[[trycont]]
    170 
    171 // CHECK: [[trycont]]
    172 // CHECK-NEXT: ret i32 1
    173 
    174 // CHECK-LABEL: define internal void @"\01?fin$0@0@nested___except___finally@@"(i8 %abnormal_termination, i8* %frame_pointer)
    175 // CHECK: call void @g()
    176 // CHECK: unreachable
    177 
    178 int nested___except___except() {
    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 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 {{.*}} [i8* 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 {{.*}} [i8* null]
    211 // CHECK: catchret
    212 // CHECK: br label %[[trycont4:[^ ]*]]
    213 
    214 // CHECK: [[trycont4]]
    215 // CHECK-NEXT: ret i32 1
    216 
    217 // CHECK: [[g2_cont]]
    218 // CHECK-NEXT: br label %[[tryleave:[^ ]*]]
    219 // CHECK-NOT: store i32 23
    220 
    221 // CHECK: [[g1_cont]]
    222 // CHECK: store i32 16, i32* %myres
    223 // CHECK-NEXT: br label %[[trycont:[^ ]*]]
    224 
    225 // CHECK: [[trycont]]
    226 // CHECK-NEXT: store i32 51, i32* %myres
    227 // CHECK-NEXT: br label %[[tryleave]]
    228 
    229 // CHECK: [[tryleave]]
    230 // CHECK-NEXT: br label %[[trycont4]]
    231 
    232 int nested___finally___except() {
    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 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: catchpad
    257 // CHECK: catchret
    258 // 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: 23
    264 
    265 // CHECK: [[g1_cont]]
    266 // CHECK-NEXT: br label %[[trycont:[^ ]*]]
    267 
    268 // CHECK: [[trycont]]
    269 // CHECK: store i32 51, i32* %
    270 // CHECK-NEXT: br label %[[tryleave]]
    271 
    272 // CHECK: [[tryleave]]
    273 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
    274 // CHECK-NEXT: call void @"\01?fin$0@0@nested___finally___except@@"(i8 0, i8* %[[fp]])
    275 // CHECK-NEXT: ret i32 1
    276 
    277 // CHECK: [[g2_lpad]]
    278 // CHECK: cleanuppad
    279 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
    280 // CHECK-NEXT: call void @"\01?fin$0@0@nested___finally___except@@"(i8 1, i8* %[[fp]])
    281 // CHECK: cleanupret {{.*}} unwind to caller
    282 
    283 // CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___except@@"(i8 %abnormal_termination, i8* %frame_pointer)
    284 // CHECK: ret void
    285 
    286 int nested___finally___finally() {
    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 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, i32* %[[myres:[^ ]*]],
    312 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
    313 // CHECK-NEXT: invoke void @"\01?fin$1@0@nested___finally___finally@@"(i8 0, i8* %[[fp]])
    314 // CHECK-NEXT:       to label %[[finally_cont:.*]] unwind label %[[g2_lpad:.*]]
    315 
    316 // CHECK: [[finally_cont]]
    317 // CHECK: store i32 51, i32* %[[myres]]
    318 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
    319 // CHECK-NEXT: call void @"\01?fin$0@0@nested___finally___finally@@"(i8 0, i8* %[[fp]])
    320 // CHECK-NEXT: ret i32 1
    321 
    322 // CHECK: [[g1_lpad]]
    323 // CHECK-NEXT: %[[padtoken:[^ ]*]] = cleanuppad within none []
    324 // CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
    325 // CHECK-NEXT: invoke void @"\01?fin$1@0@nested___finally___finally@@"(i8 1, i8* %[[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 i8* @llvm.localaddress()
    333 // CHECK-NEXT: call void @"\01?fin$0@0@nested___finally___finally@@"(i8 1, i8* %[[fp]])
    334 // CHECK: cleanupret from %[[padtoken]] unwind to caller
    335 
    336 // CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___finally@@"(i8 %abnormal_termination, i8* %frame_pointer)
    337 // CHECK: ret void
    338 
    339 // CHECK-LABEL: define internal void @"\01?fin$1@0@nested___finally___finally@@"(i8 %abnormal_termination, i8* %frame_pointer)
    340 // CHECK: call void @g()
    341 // CHECK: unreachable
    342