aboutsummaryrefslogtreecommitdiff
path: root/test/Sema/warn-unreachable.c
blob: fd74b5c87175e5098c4d34aaf696dd60776548c8 (plain) (blame)
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
// RUN: %clang %s -fsyntax-only -Xclang -verify -fblocks -Wunreachable-code -Wno-unused-value -Wno-covered-switch-default

int halt() __attribute__((noreturn));
int live();
int dead();

void test1() {
  goto c;
  d:
  goto e;       // expected-warning {{will never be executed}}
  c: ;
  int i;
  return;
  goto b;        // expected-warning {{will never be executed}}
  goto a;        // expected-warning {{will never be executed}}
  b:
  i = 1;
  a:
  i = 2;
  goto f;
  e:
  goto d;
  f: ;
}

void test2() {
  int i;
  switch (live()) {
  case 1:
    halt(),
      dead();   // expected-warning {{will never be executed}}

  case 2:
    live(), halt(),
      dead();   // expected-warning {{will never be executed}}

  case 3:
  live()
    +           // expected-warning {{will never be executed}}
    halt();
  dead();

  case 4:
  a4:
    live(),
      halt();
    goto a4;    // expected-warning {{will never be executed}}

  case 5:
    goto a5;
  c5:
    dead();     // expected-warning {{will never be executed}}
    goto b5;
  a5:
    live(),
      halt();
  b5:
    goto c5;

  case 6:
    if (live())
      goto e6;
    live(),
      halt();
  d6:
    dead();     // expected-warning {{will never be executed}}
    goto b6;
  c6:
    dead();
    goto b6;
  e6:
    live(),
      halt();
  b6:
    goto c6;
  case 7:
    halt()
      +
      dead();   // expected-warning {{will never be executed}}
    -           // expected-warning {{will never be executed}}
      halt();
  case 8:
    i
      +=        // expected-warning {{will never be executed}}
      halt();
  case 9:
    halt()
      ?         // expected-warning {{will never be executed}}
      dead() : dead();
  case 10:
    (           // expected-warning {{will never be executed}}
      float)halt();
  case 11: {
    int a[5];
    live(),
      a[halt()
        ];      // expected-warning {{will never be executed}}
  }
  }
}

enum Cases { C1, C2, C3 };
int test_enum_cases(enum Cases C) {
  switch (C) {
    case C1:
    case C2:
    case C3:
      return 1;
    default: {
      int i = 0; // expected-warning{{will never be executed}}
      ++i;
      return i;
    }
  }  
}

// Handle unreachable code triggered by macro expansions.
void __myassert_rtn(const char *, const char *, int, const char *) __attribute__((__noreturn__));

#define myassert(e) \
    (__builtin_expect(!(e), 0) ? __myassert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)

void test_assert() {
  myassert(0 && "unreachable");
  return; // no-warning
}

// Test case for PR 9774.  Tests that dead code in macros aren't warned about.
#define MY_MAX(a,b)     ((a) >= (b) ? (a) : (b))
void PR9774(int *s) {
    for (int i = 0; i < MY_MAX(2, 3); i++) // no-warning
        s[i] = 0;
}

// Test case for <rdar://problem/11005770>.  We should treat code guarded
// by 'x & 0' and 'x * 0' as unreachable.
void calledFun();
void test_mul_and_zero(int x) {
  if (x & 0) calledFun(); // expected-warning {{will never be executed}}
  if (0 & x) calledFun(); // expected-warning {{will never be executed}}
  if (x * 0) calledFun(); // expected-warning {{will never be executed}}
  if (0 * x) calledFun(); // expected-warning {{will never be executed}}
}