Oh, I see. You're right, that's another bug in the old code, but easy
enough to fix. Here's the fixed patch and a test case.

If you want to optimize things, it would be great if we wouldn't end
up storing each VLA pointer twice—having it on the stack once should
be enough. I think we should be able to get away with simply setting
*vla_sp_loc to c in the initializers...

On Tue, Apr 28, 2015 at 6:52 AM, Sergey Korshunoff <[email protected]> wrote:
> Hi, Philip! A nice work :-)
>
>> PS: patch 4 can be wrong for the case of the multiple VLA declaration
>> As I understand, SP will be saved only after vla1.
>
> Let's continue. Testing a current mob tcc with 1..4 patches added.
> A test program:
>
> void test2()
> {
>   unsigned long our_sp;
>   int count = 10;
>   void *addr[count];
>   void *addr2[count];
>   void *addr3[count];
>
>     __asm__ ("\t movl %%esp,%0" : "=m"(our_sp));
>     fprintf(stderr,"1: SP=%p\n", (void *)our_sp);
>
>   for(;count--;) {
>     int a[f()];
>
>     addr[count] = a;
>
>     continue;
>   }
>
>     __asm__ ("\t movl %%esp,%0" : "=m"(our_sp));
>     fprintf(stderr,"2: SP=%p\n", (void *)our_sp);
>
>   if(addr[9] == addr[0]) {
>     printf("OK\n");
>   } else {
>     printf("NOT OK\n");
>   }
> }
>
> A test compiled by gcc:
> 1: SP=0xbf896260
> 2: SP=0xbf896260
> OK
>
> A test compiled by tcc:
> 1: SP=0xbff62dc0
> 2: SP=0xbff62e20
> OK
>
> _______________________________________________
> Tinycc-devel mailing list
> [email protected]
> https://lists.nongnu.org/mailman/listinfo/tinycc-devel
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
_______________________________________________
Tinycc-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

Reply via email to