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
4794 } else if (tok == TOK_WHILE) {4794 } else if (tok == TOK_WHILE) {
4795 next();4795 next();
4796 d = ind;4796 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 }
4797 skip('(');4801 skip('(');
4798 gexpr();4802 gexpr();
4799 skip(')');4803 skip(')');
@@ -4958,6 +4962,13 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 158 unmodified lines
4958 /* compute jump */4962 /* compute jump */
4959 if (!csym)4963 if (!csym)
4960 tcc_error("cannot continue");4964 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 }
4961 *csym = gjmp(*csym);4972 *csym = gjmp(*csym);
4962 next();4973 next();
4963 skip(';');4974 skip(';');
@@ -4980,6 +4991,10 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 16 unmodified lines
4980 skip(';');4991 skip(';');
4981 d = ind;4992 d = ind;
4982 c = ind;4993 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 }
4983 a = 0;4998 a = 0;
4984 b = 0;4999 b = 0;
4985 if (tok != ';') {5000 if (tok != ';') {
@@ -4990,6 +5005,10 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 4 unmodified lines
4990 if (tok != ')') {5005 if (tok != ')') {
4991 e = gjmp(0);5006 e = gjmp(0);
4992 c = ind;5007 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 }
4993 gexpr();5012 gexpr();
4994 vpop();5013 vpop();
4995 gjmp_addr(d);5014 gjmp_addr(d);
@@ -5008,6 +5027,10 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 12 unmodified lines
5008 a = 0;5027 a = 0;
5009 b = 0;5028 b = 0;
5010 d = ind;5029 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 }
5011 block(&a, &b, case_sym, def_sym, case_reg, 0);5034 block(&a, &b, case_sym, def_sym, case_reg, 0);
5012 skip(TOK_WHILE);5035 skip(TOK_WHILE);
5013 skip('(');5036 skip('(');
tests/tests2/79_vla_continue.c+92−0
@@ -0,0 +1,92 @@
1#include <stdio.h>
2
3int f(void)
4{
5 return 5;
6}
7
8void 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
27void 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
46void 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
65void 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
84int 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 @@
1OK
2OK
3OK
4OK
tests/tests2/Makefile+3−2
@@ -96,8 +96,9 @@ TESTS = \ · 95 unmodified lines
96 74_nocode_wanted.test \96 74_nocode_wanted.test \
97 75_array_in_struct_init.test \97 75_array_in_struct_init.test \
98 76_dollars_in_identifiers.test \98 76_dollars_in_identifiers.test \
99 77_push_pop_macro.test \99 77_push_pop_macro.test
100 78_vla_label.test100# 78_vla_label.test -- currently broken
101# 79_vla_continue.test -- currently broken
101 102
102# 34_array_assignment.test -- array assignment is not in C standard103# 34_array_assignment.test -- array assignment is not in C standard
103 104