warning notified in bug 2613 fixed 36/536/4
Vincent COUVERT [Tue, 1 Jun 2010 08:03:59 +0000 (10:03 +0200)]
Change-Id: I82ba8f31aa457d462d59b859d8a2b2bd90d01af6

scilab/CHANGES_5.3.X
scilab/modules/core/includes/callinter.h
scilab/modules/core/src/c/scirun.c
scilab/modules/core/tests/nonreg_tests/bug_2613.dia.ref [new file with mode: 0644]
scilab/modules/core/tests/nonreg_tests/bug_2613.tst [new file with mode: 0644]

index 3e22f81..499729d 100644 (file)
@@ -344,6 +344,9 @@ Bug fixes:
 
 * bug 2076 fixed - pspect did not use the last data window.
 
+* bug 2613 fixed - Incorrect stack recovery for catched errors in some
+                   specific contexts (for loops, ..)
+
 * bug 2623 fixed - non regression test script fixed
 
 * bug 2654 partially fixed - exec returned a wrong error if line had more
index b2dde3c..256e4f0 100644 (file)
@@ -1,37 +1,38 @@
 c Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 c Copyright (C) INRIA
-c 
+c
 c This file must be used under the terms of the CeCILL.
 c This source file is licensed as described in the file COPYING, which
 c you should have received as part of this distribution.  The terms
-c are also available at    
+c are also available at
 c http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
 
-c     this  include file contains code relative to interfaces calling. 
+c     this  include file contains code relative to interfaces calling.
 c     We use
 c     include file instead of subroutine to avoid recursion pbs. This file
 c     must be included in each routine which compute an external
 
-60     call  parse
+ 60    call  parse
        if(fun.eq.99) then
-               if(err.gt.0.or.err1.gt.0) then
-c     .     test if we are under errcatch('stop') mode (imode=3)           
-                       imode = mod(abs(errct)/100000,8)
-                       if (imode.ne.3) goto 97
-               endif
-               fun = 0
-               goto 200
+          if(err.gt.0.or.err1.gt.0) then
+c       .     test if we are under errcatch('stop') mode (imode=3)
+c
+             imode = mod(abs(errct)/100000,8)
+             if (imode.ne.3) goto 97
+          endif
+          fun = 0
+          goto 200
        endif
 
        if(err.gt.0) goto 97
-c     
-c        recursion on gateway
+c
+c       recursion on gateway
        ERROR_GW_ID = -1
        END_OVERLOAD = -2
        GW_CORE_ID = 13
        GW_IO_ID = 5
        GW_USER_ID = 14
-       GW_USER2_ID = 24   
+       GW_USER2_ID = 24
        GW_FUNCTIONS_ID = 31
 
        RECURSION_CALL_COMP = 1
@@ -48,86 +49,88 @@ c     recursion on gateway
        bok = isrecursioncalltofunction()
 
        if(bok.eq.1) then
-               ir = rstk(pt) - 900
-               if (RECURSION_CALL_COMP .eq. ir) then
-c            see comp (sci_comp.f)
-                       k = GW_CORE_ID
-               else if (RECURSION_CALL_EXEC1 .eq. ir) then
-c            see exec (intexec.f)
-                       k = GW_FUNCTIONS_ID
-               else if (RECURSION_CALL_EXECSTR .eq. ir) then
-c            see execstr (intexecstr.f)
-                       k = GW_FUNCTIONS_ID
-               else if (RECURSION_CALL_SAVE .eq. ir) then
-c            see save (newsave.f)
-                       k = GW_IO_ID
-               else if (RECURSION_CALL_LOAD .eq. ir) then
-c            see load (newsave.f)
-                       k = GW_IO_ID 
-               else if (RECURSION_CALL_DEFF .eq. ir) then
-c            see deff (intdeff.f)
-c            call comp by fun & fin
-                       k = GW_FUNCTIONS_ID
-               else if (RECURSION_CALL_DISP .eq. ir) then
-c            see disp (intdisp.f)
-                       k = GW_OUTPUT_STREAM_ID
-               else if (RECURSION_CALL_EXEC2 .eq. ir) then
-c            see exec (intexec.f)
-                       k = GW_FUNCTIONS_ID
-               else if (ir .eq. 10) then 
-c            end of overloaded function
-                       k = END_OVERLOAD
-               else if(ir.gt.40) then
-c            back to gw_user2
-                       k = GW_USER2_ID
-               else if(ir.gt.20) then
-c            back to gw_user
-                       k = GW_USER_ID
-               else
-                       k = ERROR_GW_ID
-               endif
-               goto 95
+          ir = rstk(pt) - 900
+          if (RECURSION_CALL_COMP .eq. ir) then
+c       see comp (sci_comp.f)
+             k = GW_CORE_ID
+          else if (RECURSION_CALL_EXEC1 .eq. ir) then
+c       see exec (intexec.f)
+             k = GW_FUNCTIONS_ID
+          else if (RECURSION_CALL_EXECSTR .eq. ir) then
+c       see execstr (intexecstr.f)
+             k = GW_FUNCTIONS_ID
+          else if (RECURSION_CALL_SAVE .eq. ir) then
+c       see save (newsave.f)
+             k = GW_IO_ID
+          else if (RECURSION_CALL_LOAD .eq. ir) then
+c       see load (newsave.f)
+             k = GW_IO_ID
+          else if (RECURSION_CALL_DEFF .eq. ir) then
+c       see deff (intdeff.f)
+c       call comp by fun & fin
+             k = GW_FUNCTIONS_ID
+          else if (RECURSION_CALL_DISP .eq. ir) then
+c       see disp (intdisp.f)
+             k = GW_OUTPUT_STREAM_ID
+          else if (RECURSION_CALL_EXEC2 .eq. ir) then
+c       see exec (intexec.f)
+             k = GW_FUNCTIONS_ID
+          else if (ir .eq. 10) then
+c       end of overloaded function
+             k = END_OVERLOAD
+          else if(ir.gt.40) then
+c       back to gw_user2
+             k = GW_USER2_ID
+          else if(ir.gt.20) then
+c       back to gw_user
+             k = GW_USER_ID
+          else
+             k = ERROR_GW_ID
+          endif
+          goto 95
        endif
 
 c
-89     if(top.lt.rhs ) then
-               call error(22)
-               goto 97
+ 89    if(top.lt.rhs ) then
+          call error(22)
+          goto 97
        endif
 
        if(top-rhs+lhs+1.ge.bot) then
-               call error(18)
-               goto 97
+          call error(18)
+          goto 97
        endif
 
-c     ireftop used to reset top if an error occurs during the function evaluation
-       ireftop = top - max(0,rhs)
+c       stack recovery is now handled in errmgr
+c       ireftop used to reset top if an error occurs during the function
+c       evaluation
+c       ireftop = top - max(0,rhs)
 
        goto 91
-c     
-90     if(err.gt.0) goto 97
+c
+ 90    if(err.gt.0) goto 97
 
-91     k = fun
+ 91    k = fun
        fun = 0
 
        if(k.eq.krec) then
-               krec = -1
-               call error(22)
-               goto 97
+          krec = -1
+          call error(22)
+          goto 97
        endif
 
        krec = -1
 
-       if (k.eq.0 ) goto 60 
+       if (k.eq.0 ) goto 60
 
-95     continue
+ 95    continue
 
        if (k.eq.END_OVERLOAD) then
-               goto 96
+          goto 96
        endif
 
        if (k.eq.ERROR_GW_ID) then
-               goto 89
+          goto 89
        endif
 
        if (.not.allowptr(k)) call ref2val
@@ -136,34 +139,37 @@ c
 
        call callinterf(k)
 
-C      if (k.eq.krec) krec = 99999
+C       if (k.eq.krec) krec = 99999
        krec = -1
 
        if(fun.ge.0) then
-               if (top-lhs+1.gt.0) call iset(rhs,0,infstk(top-lhs+1),1)
-               if(paus.gt.0) goto 91
-               if (err1.gt.0) top = ireftop
-               goto 90
+          if (top-lhs+1.gt.0) call iset(rhs,0,infstk(top-lhs+1),1)
+          if(paus.gt.0) goto 91
+c       .  stack recovery is now handled in errmgr */
+c          if (err1.gt.0) top = ireftop
+          goto 90
        endif
-c     called interface ask for a scilab function to perform the function (fun=-1)
-c     the function name is given in ids(1,pt+1)
+c       called interface ask for a scilab function to perform the
+c       function (fun=-1)
+c       the function name is given in ids(1,pt+1)
 
-c     call ref2val removed here because if forces overloading function to
-C     be called by value
-c     call ref2val 
+c       call ref2val removed here because if forces overloading function
+c       to
+C       be called by value
+c       call ref2val
 
        fun = 0
        call funs(ids(1,pt+1))
        if(err.gt.0) goto 97
        if(fun.gt.0) then
-               if (isbyref(fun).eq.0) call ref2val
-               goto 91
+          if (isbyref(fun).eq.0) call ref2val
+          goto 91
        endif
 
        if(fin.eq.0) then
-               call error(246)
-               if(err.gt.0) goto 97
-               goto 90
+          call error(246)
+          if(err.gt.0) goto 97
+          goto 90
        endif
 
        pt = pt+1
@@ -172,15 +178,15 @@ c     call ref2val
        icall = 5
        fun = 0
 
-c     *call*  macro
+c       *call*  macro
        goto 60
-96     pt = pt - 1
+ 96    pt = pt - 1
        goto 90
 
-c     error handling
-97     if(niv.gt.0.and.paus.gt.0) then
-               fun = 0
-               goto 60
+c       error handling
+ 97    if(niv.gt.0.and.paus.gt.0) then
+          fun = 0
+          goto 60
        endif
 
        goto 9999
index 5f66d47..c31470a 100644 (file)
@@ -1,29 +1,29 @@
 /*
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) INRIA
- * 
+ *
  * This file must be used under the terms of the CeCILL.
  * This source file is licensed as described in the file COPYING, which
  * you should have received as part of this distribution.  The terms
- * are also available at    
+ * are also available at
  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
  *
  */
 /* Code automatically translated from Fortran to C */
-/*--------------------------------------------------------------------------*/ 
+/*--------------------------------------------------------------------------*/
 #include "scirun.h"
 #include "callinterf.h"
 #include "stack-c.h"
 #include "Scierror.h"
 #include "recursionFunction.h"
 #include "exitCodeValue.h"
-/*--------------------------------------------------------------------------*/ 
+/*--------------------------------------------------------------------------*/
 extern int C2F(parse)(void);
 extern int C2F(isbyref)(int *);
-/*--------------------------------------------------------------------------*/ 
+/*--------------------------------------------------------------------------*/
 static void str_copy_buf(register char *a, register char *b, long int la, long int lb);
 
-/** 
+/**
  * This function should be completely rewritten... (F2C effect)
  * It is not understable for someone normal
  *
@@ -32,7 +32,8 @@ int C2F(scirun)(char *startupCode, long int startupCode_len)
 {
   static int k = 0;
   static int ir = 0;
-  int ireftop=0;
+  /* stack recovery is now handled in errmgr */
+  /* int ireftop=0;*/
 
   /* set instruction to execute at start-up */
   /* cha1 is comming from stack-def.h */
@@ -51,58 +52,56 @@ int C2F(scirun)(char *startupCode, long int startupCode_len)
  L60:
   C2F(parse)();
   /* @TODO : What is 99 */
-  if (C2F(com).fun == 99) 
+  if (C2F(com).fun == 99)
     {
       C2F(com).fun = 0;
       return 0;
     }
-  if (Err > 0) 
+  if (Err > 0)
     {
       if (C2F(recu).niv > 0 && C2F(recu).paus > 0) C2F(com).fun = 0;
       goto L60;
     }
-       
+
   if ( isRecursionCallToFunction() )
-  {
-         int gw = getRecursionGatewayToCall();
-         if (gw == END_OVERLOAD)
-         {
-                 --C2F(recu).pt;
-                 goto L90;
-         } 
-         else if (gw == ERROR_GW_ID)
-         {
-                 goto L89;
-         }
-         else
-         {
-                 k = gw;
-         }
-         goto L95;
-  }
+    {
+      int gw = getRecursionGatewayToCall();
+      if (gw == END_OVERLOAD)
+        {
+          --C2F(recu).pt;
+          goto L90;
+        }
+      else if (gw == ERROR_GW_ID)
+        {
+          goto L89;
+        }
+      else
+        {
+          k = gw;
+        }
+      goto L95;
+    }
 
 
  L89:
-  if (Top < Rhs) 
+  if (Top < Rhs)
     {
       SciError(22);
       if (C2F(recu).niv > 0 && C2F(recu).paus > 0) C2F(com).fun = 0;
       goto L60;
     }
-  if (Top - Rhs + Lhs + 1 >= Bot) 
+  if (Top - Rhs + Lhs + 1 >= Bot)
     {
       SciError(18);
       if (C2F(recu).niv > 0 && C2F(recu).paus > 0) C2F(com).fun = 0;
       goto L60;
     }
-  /*  C2F(errgst).toperr = Top - Max(0,Rhs);*/
-
-  ireftop=Top - Max(0,Rhs);
-  /*sciprint("scirun Top=%d, ireftop=%d, toperr=%d\n",Top,ireftop,C2F(errgst).toperr);*/
+  /* stack recovery is now handled in errmgr */
+  /*ireftop=Top - Max(0,Rhs);*/
   goto L91;
 
  L90:
-  if (Err > 0) 
+  if (Err > 0)
     {
       if (C2F(recu).niv > 0 && C2F(recu).paus > 0) C2F(com).fun = 0;
       goto L60;
@@ -110,7 +109,7 @@ int C2F(scirun)(char *startupCode, long int startupCode_len)
  L91:
   k = C2F(com).fun;
   C2F(com).fun = 0;
-  if (k == C2F(recu).krec) 
+  if (k == C2F(recu).krec)
     {
       C2F(recu).krec = -1;
       SciError(22);
@@ -119,9 +118,9 @@ int C2F(scirun)(char *startupCode, long int startupCode_len)
     }
   C2F(recu).krec = -1;
   if (k == 0) goto L60;
-    
+
  L95:
-  if (! C2F(allowptr)(&k)) 
+  if (! C2F(allowptr)(&k))
     {
       C2F(ref2val)();
     }
@@ -129,27 +128,26 @@ int C2F(scirun)(char *startupCode, long int startupCode_len)
   C2F(callinterf)(&k);
   C2F(recu).krec = -1;
   if (C2F(com).fun == -999) /* exit detected */
-  {
-       return getExitCodeValue();
-  }
-  if (C2F(com).fun >= 0) 
     {
-      if (Top - Lhs + 1 > 0) 
-       {
-         int cx0=0;
-         int cx1=0;
-         C2F(iset)(&Rhs, &cx0, &C2F(vstk).infstk[Top - Lhs], &cx1);
-       }
-      if (C2F(recu).paus > 0) 
-       {
-         goto L91;
-       }
-      if (C2F(errgst).err1 > 0) 
-       {
-         /*Top = C2F(errgst).toperr;*/
-         /*sciprint("scirun Top=%d, ireftop=%d\n",Top,ireftop);*/
-         Top = ireftop;
-       }
+      return getExitCodeValue();
+    }
+  if (C2F(com).fun >= 0)
+    {
+      if (Top - Lhs + 1 > 0)
+        {
+          int cx0=0;
+          int cx1=0;
+          C2F(iset)(&Rhs, &cx0, &C2F(vstk).infstk[Top - Lhs], &cx1);
+        }
+      if (C2F(recu).paus > 0)
+        {
+          goto L91;
+        }
+      if (C2F(errgst).err1 > 0)
+        {
+          /*stack recovery is now handled in errmgr */
+          /*Top = ireftop;*/
+        }
       goto L90;
     }
 
@@ -162,28 +160,28 @@ int C2F(scirun)(char *startupCode, long int startupCode_len)
   */
   C2F(com).fun = 0;
   C2F(funs)(&C2F(recu).ids[(C2F(recu).pt + 1) * 6 - 6]);
-  if (Err > 0) 
+  if (Err > 0)
     {
       if (C2F(recu).niv > 0 && C2F(recu).paus > 0) C2F(com).fun = 0;
       goto L60;
     }
-  if (C2F(com).fun > 0) 
+  if (C2F(com).fun > 0)
     {
-      if (C2F(isbyref)(&C2F(com).fun) == 0) 
-       {
-         C2F(ref2val)();
-       }
+      if (C2F(isbyref)(&C2F(com).fun) == 0)
+        {
+          C2F(ref2val)();
+        }
       goto L91;
     }
 
-  if (Fin == 0) 
+  if (Fin == 0)
     {
       SciError(246);
-      if (Err > 0) 
-       {
-         if (C2F(recu).niv > 0 && C2F(recu).paus > 0) C2F(com).fun = 0;
-         goto L60;
-       }
+      if (Err > 0)
+        {
+          if (C2F(recu).niv > 0 && C2F(recu).paus > 0) C2F(com).fun = 0;
+          goto L60;
+        }
       goto L90;
     }
   ++C2F(recu).pt;
@@ -196,15 +194,15 @@ int C2F(scirun)(char *startupCode, long int startupCode_len)
 
   return 0;
 }
-/*--------------------------------------------------------------------------*/ 
+/*--------------------------------------------------------------------------*/
 static void str_copy_buf(register char *a, register char *b, long int la, long int lb)
 {
   if (lb>la) strncpy(a,b,la);
-  else 
+  else
     {
       int i=0;
       strncpy(a,b,lb);
       for (i=lb;i<la;i++) a[i]= ' ';
     }
 }
-/*--------------------------------------------------------------------------*/ 
+/*--------------------------------------------------------------------------*/
diff --git a/scilab/modules/core/tests/nonreg_tests/bug_2613.dia.ref b/scilab/modules/core/tests/nonreg_tests/bug_2613.dia.ref
new file mode 100644 (file)
index 0000000..6ef7125
--- /dev/null
@@ -0,0 +1,49 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2010 - INRIA - Serge Steer
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- JVM NOT MANDATORY -->
+// <-- Non-regression test for bug 2613 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=2613
+//
+// <-- Short Description -->
+// Incorrect stack recovery for catched errors in some specific contexts
+// (for loops, ..)
+// The display comparison is mandatory to check for "stack problem fixed" warning
+clear
+// reported problem test (loop expression removal)
+function y=test()
+  y=0
+  try
+    for j=1:3;
+      error(1001);
+    end
+  catch
+    y=1
+  end
+endfunction
+if test()<>1 then bugmes();quit;end
+// temporary arguments removal
+//in try/catch
+function y=fii,y=3,error(1001),endfunction
+function y=foo(a,b,c),y=a+b+c,endfunction
+y=0;
+try
+  foo(1,fii(),2)
+catch
+  y=1;
+end
+if y<>1 then bugmes();quit;end
+//in errcatch continue mode
+function y=pipo()
+  errcatch(1001,"continue","nomessage")
+  y=foo(1,fii(),2);
+  errclear(-1)
+  errcatch()
+endfunction
+y=pipo();
+if y<>6 then bugmes();quit;end
diff --git a/scilab/modules/core/tests/nonreg_tests/bug_2613.tst b/scilab/modules/core/tests/nonreg_tests/bug_2613.tst
new file mode 100644 (file)
index 0000000..0bd0df5
--- /dev/null
@@ -0,0 +1,54 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2010 - INRIA - Serge Steer
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+
+// <-- JVM NOT MANDATORY -->
+
+// <-- Non-regression test for bug 2613 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=2613
+//
+// <-- Short Description -->
+// Incorrect stack recovery for catched errors in some specific contexts
+// (for loops, ..)
+// The display comparison is mandatory to check for "stack problem fixed" warning
+clear
+// reported problem test (loop expression removal)
+function y=test()
+  y=0
+  try
+    for j=1:3;
+      error(1001);
+    end
+  catch
+    y=1
+  end
+endfunction
+
+if test()<>1 then pause,end
+
+// temporary arguments removal
+//in try/catch
+function y=fii,y=3,error(1001),endfunction
+function y=foo(a,b,c),y=a+b+c,endfunction
+y=0;
+try
+  foo(1,fii(),2)
+catch
+  y=1;
+end
+if y<>1 then pause,end
+
+//in errcatch continue mode
+function y=pipo()
+  errcatch(1001,"continue","nomessage")
+  y=foo(1,fii(),2);
+  errclear(-1)
+  errcatch()
+endfunction
+y=pipo();
+if y<>6 then pause,end