aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tccgen.c15
-rw-r--r--tests/tests2/79_vla_continue.c24
-rw-r--r--tests/tests2/79_vla_continue.expect1
-rw-r--r--tests/tests2/Makefile6
4 files changed, 37 insertions, 9 deletions
diff --git a/tccgen.c b/tccgen.c
index 88b8c72..8c1165f 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -3480,7 +3480,7 @@ static void post_type(CType *type, AttributeDef *ad)
vla_runtime_type_size(type, &align);
gen_op('*');
- vset(&int_type, VT_LOCAL|VT_LVAL, loc);
+ vset(&int_type, VT_LOCAL|VT_LVAL, n);
vswap();
vstore();
}
@@ -4809,7 +4809,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
gsym_addr(b, d);
} else if (tok == '{') {
Sym *llabel;
- int block_vla_sp_loc, *saved_vla_sp_loc, saved_vla_flags;
+ int block_vla_sp_loc, *saved_vla_sp_loc, saved_vla_flags, *orig_vla_sp_loc;
next();
/* record local declaration stack position */
@@ -4822,7 +4822,8 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
/* save VLA state */
block_vla_sp_loc = *(saved_vla_sp_loc = vla_sp_loc);
if (saved_vla_sp_loc != &vla_sp_root_loc)
- vla_sp_loc = &block_vla_sp_loc;
+ vla_sp_loc = &block_vla_sp_loc;
+ orig_vla_sp_loc = vla_sp_loc;
saved_vla_flags = vla_flags;
vla_flags |= VLA_NEED_NEW_FRAME;
@@ -4878,10 +4879,10 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
/* Pop VLA frames and restore stack pointer if required */
if (saved_vla_sp_loc != &vla_sp_root_loc)
*saved_vla_sp_loc = block_vla_sp_loc;
- if (vla_sp_loc != (saved_vla_sp_loc == &vla_sp_root_loc ? &vla_sp_root_loc : &block_vla_sp_loc)) {
- vla_sp_loc = saved_vla_sp_loc;
- gen_vla_sp_restore(*vla_sp_loc);
+ if (vla_sp_loc != orig_vla_sp_loc) {
+ gen_vla_sp_restore(*saved_vla_sp_loc);
}
+ vla_sp_loc = saved_vla_sp_loc;
vla_flags = (vla_flags & ~VLA_SCOPE_FLAGS) | (saved_vla_flags & VLA_SCOPE_FLAGS);
next();
@@ -5482,6 +5483,8 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
vla_runtime_type_size(type, &a);
gen_vla_alloc(type, a);
+ vla_flags = VLA_IN_SCOPE;
+ vla_sp_save();
vset(type, VT_LOCAL|VT_LVAL, c);
vswap();
vstore();
diff --git a/tests/tests2/79_vla_continue.c b/tests/tests2/79_vla_continue.c
index 9c48c1d..19301e0 100644
--- a/tests/tests2/79_vla_continue.c
+++ b/tests/tests2/79_vla_continue.c
@@ -81,12 +81,36 @@ void test4()
}
}
+void test5()
+{
+ int count = 10;
+ int a[f()];
+ int c[f()];
+
+ c[0] = 42;
+
+ for(;count--;) {
+ int b[f()];
+ int i;
+ for (i=0; i<f(); i++) {
+ b[i] = count;
+ }
+ }
+
+ if (c[0] == 42) {
+ printf("OK\n");
+ } else {
+ printf("NOT OK\n");
+ }
+}
+
int main(void)
{
test1();
test2();
test3();
test4();
+ test5();
return 0;
}
diff --git a/tests/tests2/79_vla_continue.expect b/tests/tests2/79_vla_continue.expect
index b462a5a..21da4d2 100644
--- a/tests/tests2/79_vla_continue.expect
+++ b/tests/tests2/79_vla_continue.expect
@@ -2,3 +2,4 @@ OK
OK
OK
OK
+OK
diff --git a/tests/tests2/Makefile b/tests/tests2/Makefile
index 6148c0b..a441674 100644
--- a/tests/tests2/Makefile
+++ b/tests/tests2/Makefile
@@ -96,9 +96,9 @@ TESTS = \
74_nocode_wanted.test \
75_array_in_struct_init.test \
76_dollars_in_identifiers.test \
- 77_push_pop_macro.test
-# 78_vla_label.test -- currently broken
-# 79_vla_continue.test -- currently broken
+ 77_push_pop_macro.test \
+ 78_vla_label.test \
+ 79_vla_continue.test
# 34_array_assignment.test -- array assignment is not in C standard