History

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.

Philip committed 11 years ago

Commit 44c330d1 parent d2dd6fd4 files · +37 −9Browse files

Unified · Split

4 files
  1. tccgen.c +9 −6
  2. tests/tests2/79_vla_continue.c +24 −0
  3. tests/tests2/79_vla_continue.expect +1 −0
  4. tests/tests2/Makefile +3 −3
tccgen.c+9−6
@@ -3480,7 +3480,7 @@ static void post_type(CType *type, AttributeDef *ad) · 3479 unmodified lines
34803480
34813481 vla_runtime_type_size(type, &align);
34823482 gen_op('*');
3483− vset(&int_type, VT_LOCAL|VT_LVAL, loc);
3483+ vset(&int_type, VT_LOCAL|VT_LVAL, n);
34843484 vswap();
34853485 vstore();
34863486 }
@@ -4809,7 +4809,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 1322 unmodified lines
48094809 gsym_addr(b, d);
48104810 } else if (tok == '{') {
48114811 Sym *llabel;
4812− int block_vla_sp_loc, *saved_vla_sp_loc, saved_vla_flags;
4812+ int block_vla_sp_loc, *saved_vla_sp_loc, saved_vla_flags, *orig_vla_sp_loc;
48134813
48144814 next();
48154815 /* record local declaration stack position */
@@ -4822,7 +4822,8 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 6 unmodified lines
48224822 /* save VLA state */
48234823 block_vla_sp_loc = *(saved_vla_sp_loc = vla_sp_loc);
48244824 if (saved_vla_sp_loc != &vla_sp_root_loc)
4825− vla_sp_loc = &block_vla_sp_loc;
4825+ vla_sp_loc = &block_vla_sp_loc;
4826+ orig_vla_sp_loc = vla_sp_loc;
48264827
48274828 saved_vla_flags = vla_flags;
48284829 vla_flags |= VLA_NEED_NEW_FRAME;
@@ -4878,10 +4879,10 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 49 unmodified lines
48784879 /* Pop VLA frames and restore stack pointer if required */
48794880 if (saved_vla_sp_loc != &vla_sp_root_loc)
48804881 *saved_vla_sp_loc = block_vla_sp_loc;
4881− if (vla_sp_loc != (saved_vla_sp_loc == &vla_sp_root_loc ? &vla_sp_root_loc : &block_vla_sp_loc)) {
4882− vla_sp_loc = saved_vla_sp_loc;
4883− gen_vla_sp_restore(*vla_sp_loc);
4882+ if (vla_sp_loc != orig_vla_sp_loc) {
4883+ gen_vla_sp_restore(*saved_vla_sp_loc);
48844884 }
4885+ vla_sp_loc = saved_vla_sp_loc;
48854886 vla_flags = (vla_flags & ~VLA_SCOPE_FLAGS) | (saved_vla_flags & VLA_SCOPE_FLAGS);
48864887
48874888 next();
@@ -5482,6 +5483,8 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 594 unmodified lines
54825483
54835484 vla_runtime_type_size(type, &a);
54845485 gen_vla_alloc(type, a);
5486+ vla_flags = VLA_IN_SCOPE;
5487+ vla_sp_save();
54855488 vset(type, VT_LOCAL|VT_LVAL, c);
54865489 vswap();
54875490 vstore();
tests/tests2/79_vla_continue.c+24−0
@@ -81,12 +81,36 @@ void test4() · 80 unmodified lines
8181 }
8282 }
8383
84+void test5()
85+{
86+ int count = 10;
87+ int a[f()];
88+ int c[f()];
89+
90+ c[0] = 42;
91+
92+ for(;count--;) {
93+ int b[f()];
94+ int i;
95+ for (i=0; i<f(); i++) {
96+ b[i] = count;
97+ }
98+ }
99+
100+ if (c[0] == 42) {
101+ printf("OK\n");
102+ } else {
103+ printf("NOT OK\n");
104+ }
105+}
106+
84107 int main(void)
85108 {
86109 test1();
87110 test2();
88111 test3();
89112 test4();
113+ test5();
90114
91115 return 0;
92116 }
tests/tests2/79_vla_continue.expect+1−0
@@ -2,3 +2,4 @@ OK · 1 unmodified line
22 OK
33 OK
44 OK
5+OK
tests/tests2/Makefile+3−3
@@ -96,9 +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 -- currently broken
101−# 79_vla_continue.test -- currently broken
99+ 77_push_pop_macro.test \
100+ 78_vla_label.test \
101+ 79_vla_continue.test
102102
103103 # 34_array_assignment.test -- array assignment is not in C standard
104104

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t