diff options
| author | Philip <pipcet@gmail.com> | 2015-04-28 09:23:29 +0000 |
|---|---|---|
| committer | Philip <pipcet@gmail.com> | 2015-04-28 09:23:29 +0000 |
| commit | 44c330d647c3e1a17e7169f5aa5abb322166fdae (patch) | |
| tree | 156d320df5b092f03fb22035722eca749cb31f68 | |
| parent | d2dd6fdbfb491c87138eb8d7590fbb28f471ec8d (diff) | |
| download | tinycc-44c330d647c3e1a17e7169f5aa5abb322166fdae.tar.gz tinycc-44c330d647c3e1a17e7169f5aa5abb322166fdae.tar.bz2 | |
VLA fix: save stack pointer right after modification
This patch disables the optimization of saving stack pointers lazily,
which didn't fully take into account that control flow might not reach
the stack-saving instructions. I've decided to leave in the extra calls
to vla_sp_save() in case anyone wants to restore this optimization.
Tests added and enabled.
There are two remaining bugs: VLA variables can be modified, and jumping
into the scope of a declared VLA will cause a segfault rather than a
compiler error. Both of these do not affect correct C code, but should
be fixed at some point. Once VLA variables have been made properly
immutable, we can share them with the saved stack pointer and save stack
and instructions.
| -rw-r--r-- | tccgen.c | 15 | ||||
| -rw-r--r-- | tests/tests2/79_vla_continue.c | 24 | ||||
| -rw-r--r-- | tests/tests2/79_vla_continue.expect | 1 | ||||
| -rw-r--r-- | tests/tests2/Makefile | 6 |
4 files changed, 37 insertions, 9 deletions
@@ -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 |
