History

fix VLA/continue issue

as reported in http://lists.nongnu.org/archive/html/tinycc-devel/2015-04/msg00131.html. Note that this is one of two separate VLA bugs: A. labels aren't reached by program execution, so the stack pointer is never saved B. continue doesn't restore the stack pointer as goto does This fixes only B. I'm not sure whether the same issue applies to break as well as continue. Add a test case, but disable tests #78 and #79 for now as they're not fully fixed until the issue described in http://lists.nongnu.org/archive/html/tinycc-devel/2015-04/msg00110.html is resolved.

Philip committed 11 years ago

Commit d2dd6fd1 parent bd489a44 files · +122 −2Browse files

Unified · Split

4 files
  1. tccgen.c +23 −0
  2. tests/tests2/79_vla_continue.c +92 −0
  3. tests/tests2/79_vla_continue.expect +4 −0
  4. tests/tests2/Makefile +3 −2
tccgen.c+23−0
@@ -4794,6 +4794,10 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 4793 unmodified lines
47944794 } else if (tok == TOK_WHILE) {
47954795 next();
47964796 d = ind;
4797+ if (vla_flags & VLA_IN_SCOPE) {
4798+ gen_vla_sp_restore(*vla_sp_loc);
4799+ vla_flags |= VLA_NEED_NEW_FRAME;
4800+ }
47974801 skip('(');
47984802 gexpr();
47994803 skip(')');
@@ -4958,6 +4962,13 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 158 unmodified lines
49584962 /* compute jump */
49594963 if (!csym)
49604964 tcc_error("cannot continue");
4965+ if (vla_flags & VLA_IN_SCOPE) {
4966+ /* If VLAs are in use, save the current stack pointer and
4967+ reset the stack pointer to what it was at function entry
4968+ (label will restore stack pointer in inner scopes) */
4969+ vla_sp_save();
4970+ gen_vla_sp_restore(vla_sp_root_loc);
4971+ }
49614972 *csym = gjmp(*csym);
49624973 next();
49634974 skip(';');
@@ -4980,6 +4991,10 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 16 unmodified lines
49804991 skip(';');
49814992 d = ind;
49824993 c = ind;
4994+ if (vla_flags & VLA_IN_SCOPE) {
4995+ gen_vla_sp_restore(*vla_sp_loc);
4996+ vla_flags |= VLA_NEED_NEW_FRAME;
4997+ }
49834998 a = 0;
49844999 b = 0;
49855000 if (tok != ';') {
@@ -4990,6 +5005,10 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 4 unmodified lines
49905005 if (tok != ')') {
49915006 e = gjmp(0);
49925007 c = ind;
5008+ if (vla_flags & VLA_IN_SCOPE) {
5009+ gen_vla_sp_restore(*vla_sp_loc);
5010+ vla_flags |= VLA_NEED_NEW_FRAME;
5011+ }
49935012 gexpr();
49945013 vpop();
49955014 gjmp_addr(d);
@@ -5008,6 +5027,10 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 12 unmodified lines
50085027 a = 0;
50095028 b = 0;
50105029 d = ind;
5030+ if (vla_flags & VLA_IN_SCOPE) {
5031+ gen_vla_sp_restore(*vla_sp_loc);
5032+ vla_flags |= VLA_NEED_NEW_FRAME;
5033+ }
50115034 block(&a, &b, case_sym, def_sym, case_reg, 0);
50125035 skip(TOK_WHILE);
50135036 skip('(');
tests/tests2/79_vla_continue.c+92−0
@@ -0,0 +1,92 @@
1+#include <stdio.h>
2+
3+int f(void)
4+{
5+ return 5;
6+}
7+
8+void test1()
9+{
10+ int count = 10;
11+ void *addr[10];
12+ for(;count--;) {
13+ int a[f()];
14+
15+ addr[count] = a;
16+
17+ continue;
18+ }
19+
20+ if(addr[9] == addr[0]) {
21+ printf("OK\n");
22+ } else {
23+ printf("NOT OK\n");
24+ }
25+}
26+
27+void test2()
28+{
29+ int count = 10;
30+ void *addr[count];
31+ for(;count--;) {
32+ int a[f()];
33+
34+ addr[count] = a;
35+
36+ continue;
37+ }
38+
39+ if(addr[9] == addr[0]) {
40+ printf("OK\n");
41+ } else {
42+ printf("NOT OK\n");
43+ }
44+}
45+
46+void test3()
47+{
48+ int count = 10;
49+ void *addr[count];
50+ while(count--) {
51+ int a[f()];
52+
53+ addr[count] = a;
54+
55+ continue;
56+ }
57+
58+ if(addr[9] == addr[0]) {
59+ printf("OK\n");
60+ } else {
61+ printf("NOT OK\n");
62+ }
63+}
64+
65+void test4()
66+{
67+ int count = 10;
68+ void *addr[count];
69+ do {
70+ int a[f()];
71+
72+ addr[count] = a;
73+
74+ continue;
75+ } while(count--);
76+
77+ if(addr[9] == addr[0]) {
78+ printf("OK\n");
79+ } else {
80+ printf("NOT OK\n");
81+ }
82+}
83+
84+int main(void)
85+{
86+ test1();
87+ test2();
88+ test3();
89+ test4();
90+
91+ return 0;
92+}
tests/tests2/79_vla_continue.expect+4−0
@@ -0,0 +1,4 @@
1+OK
2+OK
3+OK
4+OK
tests/tests2/Makefile+3−2
@@ -96,8 +96,9 @@ TESTS = \ · 95 unmodified lines
9696 74_nocode_wanted.test \
9797 75_array_in_struct_init.test \
9898 76_dollars_in_identifiers.test \
99− 77_push_pop_macro.test \
100− 78_vla_label.test
99+ 77_push_pop_macro.test
100+# 78_vla_label.test -- currently broken
101+# 79_vla_continue.test -- currently broken
101102
102103 # 34_array_assignment.test -- array assignment is not in C standard
103104