blob: 74b1312fd229d713cd3f8cab5dd34c401f530e32 [file] [log] [blame] [edit]
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s
void sw1(int a) {
switch (int b = 1; a) {
case 0:
b = b + 1;
break;
case 1:
break;
case 2: {
b = b + 1;
int yolo = 100;
break;
}
}
}
// CHECK: cir.func @_Z3sw1i
// CHECK: cir.switch (%3 : !s32i) [
// CHECK-NEXT: case (equal, 0) {
// CHECK-NEXT: %4 = cir.load %1 : !cir.ptr<!s32i>, !s32i
// CHECK-NEXT: %5 = cir.const #cir.int<1> : !s32i
// CHECK-NEXT: %6 = cir.binop(add, %4, %5) nsw : !s32i
// CHECK-NEXT: cir.store %6, %1 : !s32i, !cir.ptr<!s32i>
// CHECK-NEXT: cir.break
// CHECK-NEXT: },
// CHECK-NEXT: case (equal, 1) {
// CHECK-NEXT: cir.break
// CHECK-NEXT: },
// CHECK-NEXT: case (equal, 2) {
// CHECK-NEXT: cir.scope {
// CHECK-NEXT: %4 = cir.alloca !s32i, !cir.ptr<!s32i>, ["yolo", init]
// CHECK-NEXT: %5 = cir.load %1 : !cir.ptr<!s32i>, !s32i
// CHECK-NEXT: %6 = cir.const #cir.int<1> : !s32i
// CHECK-NEXT: %7 = cir.binop(add, %5, %6) nsw : !s32i
// CHECK-NEXT: cir.store %7, %1 : !s32i, !cir.ptr<!s32i>
// CHECK-NEXT: %8 = cir.const #cir.int<100> : !s32i
// CHECK-NEXT: cir.store %8, %4 : !s32i, !cir.ptr<!s32i>
// CHECK-NEXT: cir.break
// CHECK-NEXT: }
// CHECK-NEXT: cir.yield
// CHECK-NEXT: }
void sw2(int a) {
switch (int yolo = 2; a) {
case 3:
// "fomo" has the same lifetime as "yolo"
int fomo = 0;
yolo = yolo + fomo;
break;
}
}
// CHECK: cir.func @_Z3sw2i
// CHECK: cir.scope {
// CHECK-NEXT: %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["yolo", init]
// CHECK-NEXT: %2 = cir.alloca !s32i, !cir.ptr<!s32i>, ["fomo", init]
// CHECK: cir.switch (%4 : !s32i) [
// CHECK-NEXT: case (equal, 3) {
// CHECK-NEXT: %5 = cir.const #cir.int<0> : !s32i
// CHECK-NEXT: cir.store %5, %2 : !s32i, !cir.ptr<!s32i>
void sw3(int a) {
switch (a) {
default:
break;
}
}
// CHECK: cir.func @_Z3sw3i
// CHECK: cir.scope {
// CHECK-NEXT: %1 = cir.load %0 : !cir.ptr<!s32i>, !s32i
// CHECK-NEXT: cir.switch (%1 : !s32i) [
// CHECK-NEXT: case (default) {
// CHECK-NEXT: cir.break
// CHECK-NEXT: }
// CHECK-NEXT: ]
int sw4(int a) {
switch (a) {
case 42: {
return 3;
}
default:
return 2;
}
return 0;
}
// CHECK: cir.func @_Z3sw4i
// CHECK: cir.switch (%4 : !s32i) [
// CHECK-NEXT: case (equal, 42) {
// CHECK-NEXT: cir.scope {
// CHECK-NEXT: %5 = cir.const #cir.int<3> : !s32i
// CHECK-NEXT: cir.store %5, %1 : !s32i, !cir.ptr<!s32i>
// CHECK-NEXT: %6 = cir.load %1 : !cir.ptr<!s32i>, !s32i
// CHECK-NEXT: cir.return %6 : !s32i
// CHECK-NEXT: }
// CHECK-NEXT: cir.yield
// CHECK-NEXT: },
// CHECK-NEXT: case (default) {
// CHECK-NEXT: %5 = cir.const #cir.int<2> : !s32i
// CHECK-NEXT: cir.store %5, %1 : !s32i, !cir.ptr<!s32i>
// CHECK-NEXT: %6 = cir.load %1 : !cir.ptr<!s32i>, !s32i
// CHECK-NEXT: cir.return %6 : !s32i
// CHECK-NEXT: }
// CHECK-NEXT: ]
void sw5(int a) {
switch (a) {
case 1:;
}
}
// CHECK: cir.func @_Z3sw5i
// CHECK: cir.switch (%1 : !s32i) [
// CHECK-NEXT: case (equal, 1) {
// CHECK-NEXT: cir.yield
void sw6(int a) {
switch (a) {
case 0:
case 1:
case 2:
break;
case 3:
case 4:
case 5:
break;
}
}
// CHECK: cir.func @_Z3sw6i
// CHECK: cir.switch (%1 : !s32i) [
// CHECK-NEXT: case (anyof, [0, 1, 2] : !s32i) {
// CHECK-NEXT: cir.break
// CHECK-NEXT: },
// CHECK-NEXT: case (anyof, [3, 4, 5] : !s32i) {
// CHECK-NEXT: cir.break
// CHECK-NEXT: }
void sw7(int a) {
switch (a) {
case 0:
case 1:
case 2:
int x;
case 3:
case 4:
case 5:
break;
}
}
// CHECK: cir.func @_Z3sw7i
// CHECK: case (anyof, [0, 1, 2] : !s32i) {
// CHECK-NEXT: cir.yield
// CHECK-NEXT: },
// CHECK-NEXT: case (anyof, [3, 4, 5] : !s32i) {
// CHECK-NEXT: cir.break
// CHECK-NEXT: }
void sw8(int a) {
switch (a)
{
case 3:
break;
case 4:
default:
break;
}
}
//CHECK: cir.func @_Z3sw8i
//CHECK: case (equal, 3)
//CHECK-NEXT: cir.break
//CHECK-NEXT: },
//CHECK-NEXT: case (equal, 4) {
//CHECK-NEXT: cir.yield
//CHECK-NEXT: }
//CHECK-NEXT: case (default) {
//CHECK-NEXT: cir.break
//CHECK-NEXT: }
void sw9(int a) {
switch (a)
{
case 3:
break;
default:
case 4:
break;
}
}
//CHECK: cir.func @_Z3sw9i
//CHECK: case (equal, 3) {
//CHECK-NEXT: cir.break
//CHECK-NEXT: }
//CHECK-NEXT: case (default) {
//CHECK-NEXT: cir.yield
//CHECK-NEXT: }
//CHECK: case (equal, 4)
//CHECK-NEXT: cir.break
//CHECK-NEXT: }
void sw10(int a) {
switch (a)
{
case 3:
break;
case 4:
default:
case 5:
break;
}
}
//CHECK: cir.func @_Z4sw10i
//CHECK: case (equal, 3)
//CHECK-NEXT: cir.break
//CHECK-NEXT: },
//CHECK-NEXT: case (equal, 4) {
//CHECK-NEXT: cir.yield
//CHECK-NEXT: }
//CHECK-NEXT: case (default) {
//CHECK-NEXT: cir.yield
//CHECK-NEXT: }
//CHECK-NEXT: case (equal, 5) {
//CHECK-NEXT: cir.break
//CHECK-NEXT: }
void sw11(int a) {
switch (a)
{
case 3:
break;
case 4:
case 5:
default:
case 6:
case 7:
break;
}
}
//CHECK: cir.func @_Z4sw11i
//CHECK: case (equal, 3)
//CHECK-NEXT: cir.break
//CHECK-NEXT: },
//CHECK-NEXT: case (anyof, [4, 5] : !s32i) {
//CHECK-NEXT: cir.yield
//CHECK-NEXT: }
//CHECK-NEXT: case (default) {
//CHECK-NEXT: cir.yield
//CHECK-NEXT: }
//CHECK-NEXT: case (anyof, [6, 7] : !s32i) {
//CHECK-NEXT: cir.break
//CHECK-NEXT: }
void sw12(int a) {
switch (a)
{
case 3:
return;
break;
}
}
// CHECK: cir.func @_Z4sw12i
// CHECK: cir.scope {
// CHECK: cir.switch
// CHECK-NEXT: case (equal, 3) {
// CHECK-NEXT: cir.return
// CHECK-NEXT: ^bb1: // no predecessors
// CHECK-NEXT: cir.break
// CHECK-NEXT: }
void sw13(int a, int b) {
switch (a) {
case 1:
switch (b) {
case 2:
break;
}
}
}
// CHECK: cir.func @_Z4sw13ii
// CHECK: cir.scope {
// CHECK: cir.switch
// CHECK-NEXT: case (equal, 1) {
// CHECK-NEXT: cir.scope {
// CHECK: cir.switch
// CHECK-NEXT: case (equal, 2) {
// CHECK-NEXT: cir.break
// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-NEXT: }
// CHECK-NEXT: cir.yield
// CHECK-NEXT: }
// CHECK: }
// CHECK: cir.return
void fallthrough(int x) {
switch (x) {
case 1:
__attribute__((fallthrough));
case 2:
break;
default:
break;
}
}
// CHECK: cir.func @_Z11fallthroughi
// CHECK: cir.scope {
// CHECK: cir.switch (%1 : !s32i) [
// CHECK-NEXT: case (equal, 1) {
// CHECK-NEXT: cir.yield
// CHECK-NEXT: },
// CHECK-NEXT: case (equal, 2) {
// CHECK-NEXT: cir.break
// CHECK-NEXT: },
// CHECK-NEXT: case (default) {
// CHECK-NEXT: cir.break
// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-NEXT: }
int unreachable_after_break_1(int a) {
switch (a) {
case(42):
break;
goto exit;
default:
return 0;
};
exit:
return -1;
}
// CHECK: cir.func @_Z25unreachable_after_break_1i
// CHECK: case (equal, 42) {
// CHECK: cir.break
// CHECK: ^bb1: // no predecessors
// CHECK: cir.goto "exit"
// CHECK: }