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
3480 3480
3481 vla_runtime_type_size(type, &align);3481 vla_runtime_type_size(type, &align);
3482 gen_op('*');3482 gen_op('*');
3483 vset(&int_type, VT_LOCAL|VT_LVAL, loc);3483 vset(&int_type, VT_LOCAL|VT_LVAL, n);
3484 vswap();3484 vswap();
3485 vstore();3485 vstore();
3486 }3486 }
@@ -4809,7 +4809,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 1322 unmodified lines
4809 gsym_addr(b, d);4809 gsym_addr(b, d);
4810 } else if (tok == '{') {4810 } else if (tok == '{') {
4811 Sym *llabel;4811 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;
4813 4813
4814 next();4814 next();
4815 /* record local declaration stack position */4815 /* 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
4822 /* save VLA state */4822 /* save VLA state */
4823 block_vla_sp_loc = *(saved_vla_sp_loc = vla_sp_loc);4823 block_vla_sp_loc = *(saved_vla_sp_loc = vla_sp_loc);
4824 if (saved_vla_sp_loc != &vla_sp_root_loc)4824 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;
4826 4827
4827 saved_vla_flags = vla_flags;4828 saved_vla_flags = vla_flags;
4828 vla_flags |= VLA_NEED_NEW_FRAME;4829 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
4878 /* Pop VLA frames and restore stack pointer if required */4879 /* Pop VLA frames and restore stack pointer if required */
4879 if (saved_vla_sp_loc != &vla_sp_root_loc)4880 if (saved_vla_sp_loc != &vla_sp_root_loc)
4880 *saved_vla_sp_loc = block_vla_sp_loc;4881 *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 if (vla_sp_loc != orig_vla_sp_loc) {
4882 vla_sp_loc = saved_vla_sp_loc;4883 gen_vla_sp_restore(*saved_vla_sp_loc);
4883 gen_vla_sp_restore(*vla_sp_loc);
4884 }4884 }
4885 vla_sp_loc = saved_vla_sp_loc;
4885 vla_flags = (vla_flags & ~VLA_SCOPE_FLAGS) | (saved_vla_flags & VLA_SCOPE_FLAGS);4886 vla_flags = (vla_flags & ~VLA_SCOPE_FLAGS) | (saved_vla_flags & VLA_SCOPE_FLAGS);
4886 4887
4887 next();4888 next();
@@ -5482,6 +5483,8 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 594 unmodified lines
5482 5483
5483 vla_runtime_type_size(type, &a);5484 vla_runtime_type_size(type, &a);
5484 gen_vla_alloc(type, a);5485 gen_vla_alloc(type, a);
5486 vla_flags = VLA_IN_SCOPE;
5487 vla_sp_save();
5485 vset(type, VT_LOCAL|VT_LVAL, c);5488 vset(type, VT_LOCAL|VT_LVAL, c);
5486 vswap();5489 vswap();
5487 vstore();5490 vstore();
tests/tests2/79_vla_continue.c+24−0
@@ -81,12 +81,36 @@ void test4() · 80 unmodified lines
81 }81 }
82}82}
83 83
84void 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
84int main(void)107int main(void)
85{108{
86 test1();109 test1();
87 test2();110 test2();
88 test3();111 test3();
89 test4();112 test4();
113 test5();
90 114
91 return 0;115 return 0;
92}116}
tests/tests2/79_vla_continue.expect+1−0
@@ -2,3 +2,4 @@ OK · 1 unmodified line
2OK2OK
3OK3OK
4OK4OK
5OK
tests/tests2/Makefile+3−3
@@ -96,9 +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.test99 77_push_pop_macro.test \
100# 78_vla_label.test -- currently broken100 78_vla_label.test \
101# 79_vla_continue.test -- currently broken101 79_vla_continue.test
102 102
103# 34_array_assignment.test -- array assignment is not in C standard103# 34_array_assignment.test -- array assignment is not in C standard
104 104

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