| @@ -120,7 +120,7 @@ short nb_temp_local_vars; · 119 unmodified lines |
| 120 | 120 | |
| 121 | 121 | static struct scope { |
| 122 | 122 | struct scope *prev; |
| 123 | | − struct { int loc, num; } vla; |
| 123 | + struct { int loc, locorig, num; } vla; |
| 124 | 124 | struct { Sym *s; int n; } cl; |
| 125 | 125 | int *bsym, *csym; |
| 126 | 126 | Sym *lstk, *llstk; |
| @@ -7268,8 +7268,12 @@ static void vla_restore(int loc) · 7141 unmodified lines |
| 7268 | 7268 | |
| 7269 | 7269 | static void vla_leave(struct scope *o) |
| 7270 | 7270 | { |
| 7271 | | − if (o->vla.num < cur_scope->vla.num) |
| 7272 | | − vla_restore(o->vla.loc); |
| 7271 | + struct scope *c = cur_scope, *v = NULL; |
| 7272 | + for (; c != o && c; c = c->prev) |
| 7273 | + if (c->vla.num) |
| 7274 | + v = c; |
| 7275 | + if (v) |
| 7276 | + vla_restore(v->vla.locorig); |
| 7273 | 7277 | } |
| 7274 | 7278 | |
| 7275 | 7279 | /* ------------------------------------------------------------------------- */ |
| @@ -7281,6 +7285,7 @@ void new_scope(struct scope *o) · 5 unmodified lines |
| 7281 | 7285 | *o = *cur_scope; |
| 7282 | 7286 | o->prev = cur_scope; |
| 7283 | 7287 | cur_scope = o; |
| 7288 | + cur_scope->vla.num = 0; |
| 7284 | 7289 | |
| 7285 | 7290 | /* record local declaration stack position */ |
| 7286 | 7291 | o->lstk = local_stack; |
| @@ -7600,7 +7605,8 @@ again: · 313 unmodified lines |
| 7600 | 7605 | goto block_after_label; |
| 7601 | 7606 | |
| 7602 | 7607 | } else if (t == TOK_GOTO) { |
| 7603 | | − vla_restore(root_scope->vla.loc); |
| 7608 | + if (cur_scope->vla.num) |
| 7609 | + vla_restore(cur_scope->vla.locorig); |
| 7604 | 7610 | if (tok == '*' && gnu_ext) { |
| 7605 | 7611 | /* computed goto */ |
| 7606 | 7612 | next(); |
| @@ -8566,11 +8572,14 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 959 unmodified lines |
| 8566 | 8572 | if (NODATA_WANTED) |
| 8567 | 8573 | goto no_alloc; |
| 8568 | 8574 | |
| 8569 | | − /* save current stack pointer */ |
| 8570 | | − if (root_scope->vla.loc == 0) { |
| 8571 | | − struct scope *v = cur_scope; |
| 8572 | | − gen_vla_sp_save(loc -= PTR_SIZE); |
| 8573 | | − do v->vla.loc = loc; while ((v = v->prev)); |
| 8575 | + /* save before-VLA stack pointer if needed */ |
| 8576 | + if (cur_scope->vla.num == 0) { |
| 8577 | + if (cur_scope->prev && cur_scope->prev->vla.num) { |
| 8578 | + cur_scope->vla.locorig = cur_scope->prev->vla.loc; |
| 8579 | + } else { |
| 8580 | + gen_vla_sp_save(loc -= PTR_SIZE); |
| 8581 | + cur_scope->vla.locorig = loc; |
| 8582 | + } |
| 8574 | 8583 | } |
| 8575 | 8584 | |
| 8576 | 8585 | vla_runtime_type_size(type, &a); |