mirror of
https://github.com/mirror/tinycc.git
synced 2025-01-15 05:20:06 +08:00
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.
This commit is contained in:
parent
bd489a4815
commit
d2dd6fdbfb
23
tccgen.c
23
tccgen.c
@ -4794,6 +4794,10 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
|
|||||||
} else if (tok == TOK_WHILE) {
|
} else if (tok == TOK_WHILE) {
|
||||||
next();
|
next();
|
||||||
d = ind;
|
d = ind;
|
||||||
|
if (vla_flags & VLA_IN_SCOPE) {
|
||||||
|
gen_vla_sp_restore(*vla_sp_loc);
|
||||||
|
vla_flags |= VLA_NEED_NEW_FRAME;
|
||||||
|
}
|
||||||
skip('(');
|
skip('(');
|
||||||
gexpr();
|
gexpr();
|
||||||
skip(')');
|
skip(')');
|
||||||
@ -4958,6 +4962,13 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
|
|||||||
/* compute jump */
|
/* compute jump */
|
||||||
if (!csym)
|
if (!csym)
|
||||||
tcc_error("cannot continue");
|
tcc_error("cannot continue");
|
||||||
|
if (vla_flags & VLA_IN_SCOPE) {
|
||||||
|
/* If VLAs are in use, save the current stack pointer and
|
||||||
|
reset the stack pointer to what it was at function entry
|
||||||
|
(label will restore stack pointer in inner scopes) */
|
||||||
|
vla_sp_save();
|
||||||
|
gen_vla_sp_restore(vla_sp_root_loc);
|
||||||
|
}
|
||||||
*csym = gjmp(*csym);
|
*csym = gjmp(*csym);
|
||||||
next();
|
next();
|
||||||
skip(';');
|
skip(';');
|
||||||
@ -4980,6 +4991,10 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
|
|||||||
skip(';');
|
skip(';');
|
||||||
d = ind;
|
d = ind;
|
||||||
c = ind;
|
c = ind;
|
||||||
|
if (vla_flags & VLA_IN_SCOPE) {
|
||||||
|
gen_vla_sp_restore(*vla_sp_loc);
|
||||||
|
vla_flags |= VLA_NEED_NEW_FRAME;
|
||||||
|
}
|
||||||
a = 0;
|
a = 0;
|
||||||
b = 0;
|
b = 0;
|
||||||
if (tok != ';') {
|
if (tok != ';') {
|
||||||
@ -4990,6 +5005,10 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
|
|||||||
if (tok != ')') {
|
if (tok != ')') {
|
||||||
e = gjmp(0);
|
e = gjmp(0);
|
||||||
c = ind;
|
c = ind;
|
||||||
|
if (vla_flags & VLA_IN_SCOPE) {
|
||||||
|
gen_vla_sp_restore(*vla_sp_loc);
|
||||||
|
vla_flags |= VLA_NEED_NEW_FRAME;
|
||||||
|
}
|
||||||
gexpr();
|
gexpr();
|
||||||
vpop();
|
vpop();
|
||||||
gjmp_addr(d);
|
gjmp_addr(d);
|
||||||
@ -5008,6 +5027,10 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
|
|||||||
a = 0;
|
a = 0;
|
||||||
b = 0;
|
b = 0;
|
||||||
d = ind;
|
d = ind;
|
||||||
|
if (vla_flags & VLA_IN_SCOPE) {
|
||||||
|
gen_vla_sp_restore(*vla_sp_loc);
|
||||||
|
vla_flags |= VLA_NEED_NEW_FRAME;
|
||||||
|
}
|
||||||
block(&a, &b, case_sym, def_sym, case_reg, 0);
|
block(&a, &b, case_sym, def_sym, case_reg, 0);
|
||||||
skip(TOK_WHILE);
|
skip(TOK_WHILE);
|
||||||
skip('(');
|
skip('(');
|
||||||
|
92
tests/tests2/79_vla_continue.c
Normal file
92
tests/tests2/79_vla_continue.c
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int f(void)
|
||||||
|
{
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test1()
|
||||||
|
{
|
||||||
|
int count = 10;
|
||||||
|
void *addr[10];
|
||||||
|
for(;count--;) {
|
||||||
|
int a[f()];
|
||||||
|
|
||||||
|
addr[count] = a;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(addr[9] == addr[0]) {
|
||||||
|
printf("OK\n");
|
||||||
|
} else {
|
||||||
|
printf("NOT OK\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test2()
|
||||||
|
{
|
||||||
|
int count = 10;
|
||||||
|
void *addr[count];
|
||||||
|
for(;count--;) {
|
||||||
|
int a[f()];
|
||||||
|
|
||||||
|
addr[count] = a;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(addr[9] == addr[0]) {
|
||||||
|
printf("OK\n");
|
||||||
|
} else {
|
||||||
|
printf("NOT OK\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test3()
|
||||||
|
{
|
||||||
|
int count = 10;
|
||||||
|
void *addr[count];
|
||||||
|
while(count--) {
|
||||||
|
int a[f()];
|
||||||
|
|
||||||
|
addr[count] = a;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(addr[9] == addr[0]) {
|
||||||
|
printf("OK\n");
|
||||||
|
} else {
|
||||||
|
printf("NOT OK\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test4()
|
||||||
|
{
|
||||||
|
int count = 10;
|
||||||
|
void *addr[count];
|
||||||
|
do {
|
||||||
|
int a[f()];
|
||||||
|
|
||||||
|
addr[count] = a;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
} while(count--);
|
||||||
|
|
||||||
|
if(addr[9] == addr[0]) {
|
||||||
|
printf("OK\n");
|
||||||
|
} else {
|
||||||
|
printf("NOT OK\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
test1();
|
||||||
|
test2();
|
||||||
|
test3();
|
||||||
|
test4();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
4
tests/tests2/79_vla_continue.expect
Normal file
4
tests/tests2/79_vla_continue.expect
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
OK
|
||||||
|
OK
|
||||||
|
OK
|
||||||
|
OK
|
@ -96,8 +96,9 @@ TESTS = \
|
|||||||
74_nocode_wanted.test \
|
74_nocode_wanted.test \
|
||||||
75_array_in_struct_init.test \
|
75_array_in_struct_init.test \
|
||||||
76_dollars_in_identifiers.test \
|
76_dollars_in_identifiers.test \
|
||||||
77_push_pop_macro.test \
|
77_push_pop_macro.test
|
||||||
78_vla_label.test
|
# 78_vla_label.test -- currently broken
|
||||||
|
# 79_vla_continue.test -- currently broken
|
||||||
|
|
||||||
# 34_array_assignment.test -- array assignment is not in C standard
|
# 34_array_assignment.test -- array assignment is not in C standard
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user