reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
  193
  194
  195
  196
  197
  198
  199
  200
  201
  202
  203
  204
  205
  206
  207
  208
  209
  210
  211
  212
  213
// RUN: %clang_cc1 -triple i386-unknown-unknown -O3 %s -emit-llvm -o - | FileCheck %s

int foo(int i) {
  int j = 0;
  switch (i) {
  case -1:
    j = 1; break;
  case 1 :
    j = 2; break;
  case 2:
    j = 3; break;
  default:
    j = 42; break;
  }
  j = j + 1;
  return j;
}

int foo2(int i) {
  int j = 0;
  switch (i) {
  case 1 :
    j = 2; break;
  case 2 ... 10:
    j = 3; break;
  default:
    j = 42; break;
  }
  j = j + 1;
  return j;
}

int foo3(int i) {
  int j = 0;
  switch (i) {
  default:
    j = 42; break;
  case 111:
    j = 111; break;
  case 0 ... 100:
    j = 1; break;
  case 222:
    j = 222; break;
  }
  return j;
}


static int foo4(int i) {
  int j = 0;
  switch (i) {
  case 111:
    j = 111; break;
  case 0 ... 100:
    j = 1; break;
  case 222:
    j = 222; break;
  default:
    j = 42; break;
  case 501 ... 600:
    j = 5; break;
  }
  return j;
}

// CHECK-LABEL: define i32 @foo4t()
// CHECK: ret i32 376
// CHECK: }
int foo4t() {
  // 111 + 1 + 222 + 42 = 376
  return foo4(111) + foo4(99) + foo4(222) + foo4(601);
}

// CHECK-LABEL: define void @foo5()
// CHECK-NOT: switch
// CHECK: }
void foo5(){
    switch(0){
    default:
        if (0) {

        }
    }
}

// CHECK-LABEL: define void @foo6()
// CHECK-NOT: switch
// CHECK: }
void foo6(){
    switch(0){
    }
}

// CHECK-LABEL: define void @foo7()
// CHECK-NOT: switch
// CHECK: }
void foo7(){
    switch(0){
      foo7();
    }
}


// CHECK-LABEL: define i32 @f8(
// CHECK: ret i32 3
// CHECK: }
int f8(unsigned x) {
  switch(x) {
  default:
    return 3;
  case 0xFFFFFFFF ... 1: // This range should be empty because x is unsigned.
    return 0;
  }
}

// Ensure that default after a case range is not ignored.
//
// CHECK-LABEL: define i32 @f9()
// CHECK: ret i32 10
// CHECK: }
static int f9_0(unsigned x) {
  switch(x) {
  case 10 ... 0xFFFFFFFF:
    return 0;
  default:
    return 10;
  }
}
int f9() {
  return f9_0(2);
}

// Ensure that this doesn't compile to infinite loop in g() due to
// miscompilation of fallthrough from default to a (tested) case
// range.
//
// CHECK-LABEL: define i32 @f10()
// CHECK: ret i32 10
// CHECK: }
static int f10_0(unsigned x) {
  switch(x) {
  default:
    x += 1;
  case 10 ... 0xFFFFFFFF:
    return 0;
  }
}

int f10() {
  f10_0(1);
  return 10;
}

// This generated incorrect code because of poor switch chaining.
//
// CHECK-LABEL: define i32 @f11(
// CHECK: ret i32 3
// CHECK: }
int f11(int x) {
  switch(x) {
  default:
    return 3;
  case 10 ... 0xFFFFFFFF:
    return 0;
  }
}

// This just asserted because of the way case ranges were calculated.
//
// CHECK-LABEL: define i32 @f12(
// CHECK: ret i32 3
// CHECK: }
int f12(int x) {
  switch (x) {
  default:
    return 3;
  case 10 ... -1: 
    return 0;
  }
}

// Make sure return is not constant (if empty range is skipped or miscompiled)
//
// CHECK-LABEL: define i32 @f13(
// CHECK: ret i32 %
// CHECK: }
int f13(unsigned x) {
  switch(x) {
  case 2:
    // fallthrough empty range
  case 10 ... 9:
    return 10;
  default:
    return 0;
  }
}

// Don't delete a basic block that we want to introduce later references to.
// This isn't really specific to switches, but it's easy to show with them.
// rdar://problem/8837067
int f14(int x) {
  switch (x) {

  // case range so that the case block has no predecessors
  case 0 ... 15:
    // any expression which doesn't introduce a new block
    (void) 0;
    // kaboom

  default:
    return x;
  }
}