Fix fallthrough of non-entered stmt expressions
[tinycc.git] / tests / tests2 / 87_dead_code.c
blob369f4bab681ed84c9882df33dc8fbe69b1c1ebd3
1 /* This checks various ways of dead code inside if statements
2 where there are non-obvious ways of how the code is actually
3 not dead due to reachable by labels. */
4 extern int printf (const char *, ...);
5 static void kb_wait_1(void)
7 unsigned long timeout = 2;
8 do {
9 /* Here the else arm is a statement expression that's supposed
10 to be suppressed. The label inside the while would unsuppress
11 code generation again if not handled correctly. And that
12 would wreak havoc to the cond-expression because there's no
13 jump-around emitted, the whole statement expression really
14 needs to not generate code (perhaps except useless forward jumps). */
15 (1 ?
16 printf("timeout=%ld\n", timeout) :
18 int i = 1;
19 while (1)
20 while (i--)
21 some_label:
22 printf("error\n");
23 goto some_label;
26 timeout--;
27 } while (timeout);
30 static int global;
32 static void foo(int i)
34 global+=i;
35 printf ("g=%d\n", global);
38 static int check(void)
40 printf ("check %d\n", global);
41 return 1;
44 static void dowhile(void)
46 do {
47 foo(1);
48 if (global == 1) {
49 continue;
50 } else if (global == 2) {
51 continue;
53 /* The following break shouldn't disable the check() call,
54 as it's reachable by the continues above. */
55 break;
56 } while (check());
59 static void nondead_after_dead_return(void)
61 /* This statement expr is not entered, and hence that fact that it
62 doesn't fall-through should not influence the surrounding code. */
63 0 && ({ return; 0;});
64 printf ("nondead works\n");
65 return;
68 int main (void)
70 int i = 1;
71 kb_wait_1();
73 /* Simple test of dead code at first sight which isn't actually dead. */
74 if (0) {
75 yeah:
76 printf ("yeah\n");
77 } else {
78 printf ("boo\n");
80 if (i--)
81 goto yeah;
83 /* Some more non-obvious uses where the problems are loops, so that even
84 the first loop statements aren't actually dead. */
85 i = 1;
86 if (0) {
87 while (i--) {
88 printf ("once\n");
89 enterloop:
90 printf ("twice\n");
93 if (i >= 0)
94 goto enterloop;
96 /* The same with statement expressions. One might be tempted to
97 handle them specially by counting if inside statement exprs and
98 not unsuppressing code at loops at all then.
99 See kb_wait_1 for the other side of the medal where that wouldn't work. */
100 i = ({
101 int j = 1;
102 if (0) {
103 while (j--) {
104 printf ("SEonce\n");
105 enterexprloop:
106 printf ("SEtwice\n");
109 if (j >= 0)
110 goto enterexprloop;
111 j; });
113 /* The other two loop forms: */
114 i = 1;
115 if (0) {
116 for (i = 1; i--;) {
117 printf ("once2\n");
118 enterloop2:
119 printf ("twice2\n");
122 if (i > 0)
123 goto enterloop2;
125 i = 1;
126 if (0) {
127 do {
128 printf ("once3\n");
129 enterloop3:
130 printf ("twice3\n");
131 } while (i--);
133 if (i > 0)
134 goto enterloop3;
136 /* And check that case and default labels have the same effect
137 of disabling code suppression. */
138 i = 41;
139 switch (i) {
140 if (0) {
141 printf ("error\n");
142 case 42:
143 printf ("error2\n");
144 case 41:
145 printf ("caseok\n");
149 i = 41;
150 switch (i) {
151 if (0) {
152 printf ("error3\n");
153 default:
154 printf ("caseok2\n");
155 break;
156 case 42:
157 printf ("error4\n");
161 dowhile();
162 nondead_after_dead_return();
164 return 0;