unreachable-code-path.c revision ade3195a201e16e989e9f93a568fb1806519077c
1// RUN: %clang_cc1 -analyze -analyzer-checker=core,deadcode.DeadStores,core.experimental.UnreachableCode -verify -analyzer-opt-analyze-nested-blocks -Wno-unused-value %s
2
3extern void foo(int a);
4
5// The first few tests are non-path specific - we should be able to find them
6
7void test(unsigned a) {
8  switch (a) {
9    a += 5; // expected-warning{{never executed}}
10  case 2:
11    a *= 10;
12  case 3:
13    a %= 2;
14  }
15  foo(a);
16}
17
18void test2(unsigned a) {
19 help:
20  if (a > 0)
21    return;
22  if (a == 0)
23    return;
24  foo(a); // expected-warning{{never executed}}
25  goto help;
26}
27
28void test3(unsigned a) {
29  while(1);
30  if (a > 5) { // expected-warning{{never executed}}
31    return;
32  }
33}
34
35// These next tests are path-sensitive
36
37void test4() {
38  int a = 5;
39
40  while (a > 1)
41    a -= 2;
42
43  if (a > 1) {
44    a = a + 56; // expected-warning{{never executed}}
45  }
46
47  foo(a);
48}
49
50extern void bar(char c);
51
52void test5(const char *c) {
53  foo(c[0]);
54
55  if (!c) {
56    bar(1); // expected-warning{{never executed}}
57  }
58}
59
60// These next tests are false positives and should not generate warnings
61
62void test6(const char *c) {
63  if (c) return;
64  if (!c) return;
65  __builtin_unreachable(); // no-warning
66}
67
68// Compile-time constant false positives
69#define CONSTANT 0
70enum test_enum { Off, On };
71void test7() {
72  if (CONSTANT)
73    return; // no-warning
74
75  if (sizeof(int))
76    return; // no-warning
77
78  if (Off)
79    return; // no-warning
80}
81
82void test8() {
83  static unsigned a = 0;
84
85  if (a)
86    a = 123; // no-warning
87
88  a = 5;
89}
90
91// Check for bugs where multiple statements are reported
92void test9(unsigned a) {
93  switch (a) {
94    if (a) // expected-warning{{never executed}}
95      foo(a + 5); // no-warning
96    else          // no-warning
97      foo(a);     // no-warning
98    case 1:
99    case 2:
100      break;
101    default:
102      break;
103  }
104}
105
106// Tests from flow-sensitive version
107void test10() {
108  goto c;
109  d:
110  goto e; // expected-warning {{never executed}}
111  c: ;
112  int i;
113  return;
114  goto b; // expected-warning {{never executed}}
115  goto a; // expected-warning {{never executed}}
116  b:
117  i = 1; // no-warning
118  a:
119  i = 2;  // no-warning
120  goto f;
121  e:
122  goto d;
123  f: ;
124}
125