diff --git a/src/stats.c b/src/stats.c index fcacb47b06..fcc7f5503f 100644 --- a/src/stats.c +++ b/src/stats.c @@ -260,7 +260,7 @@ UInt ExecIfElif ( for ( i = 1; i <= nr; i++ ) { /* if the condition evaluates to 'true', execute the branch body */ - SET_BRK_CURR_STAT( stat ); +// SET_BRK_CURR_STAT( stat ); cond = ADDR_STAT(stat)[2*(i-1)]; if ( EVAL_BOOL_EXPR( cond ) != False ) { @@ -291,7 +291,7 @@ UInt ExecIfElifElse ( for ( i = 1; i <= nr; i++ ) { /* if the condition evaluates to 'true', execute the branch body */ - SET_BRK_CURR_STAT( stat ); + // SET_BRK_CURR_STAT( stat ); cond = ADDR_STAT(stat)[2*(i-1)]; if ( EVAL_BOOL_EXPR( cond ) != False ) { @@ -368,7 +368,6 @@ static ALWAYS_INLINE UInt ExecForHelper(Stat stat, UInt nr) } /* evaluate the list */ - SET_BRK_CURR_STAT( stat ); list = EVAL_EXPR( ADDR_STAT(stat)[1] ); /* get the body */ @@ -512,7 +511,6 @@ static ALWAYS_INLINE UInt ExecForRangeHelper(Stat stat, UInt nr) lvar = LVAR_REFLVAR( ADDR_STAT(stat)[0] ); /* evaluate the range */ - SET_BRK_CURR_STAT( stat ); VisitStatIfHooked(ADDR_STAT(stat)[1]); elm = EVAL_EXPR( ADDR_EXPR( ADDR_STAT(stat)[1] )[0] ); while ( ! IS_INTOBJ(elm) ) { @@ -682,8 +680,12 @@ static ALWAYS_INLINE UInt ExecWhileHelper(Stat stat, UInt nr) if (nr >= 3) body3 = ADDR_STAT(stat)[3]; + // HACK: point current "statement" at the condition expression, so + // that if there is an error in it, it resp. its location is printed, + // not the whole loop statement. + SET_BRK_CALL_TO(cond); + /* while the condition evaluates to 'true', execute the body */ - SET_BRK_CURR_STAT( stat ); while ( EVAL_BOOL_EXPR( cond ) != False ) { #if !defined(HAVE_SIGNAL) @@ -700,8 +702,10 @@ static ALWAYS_INLINE UInt ExecWhileHelper(Stat stat, UInt nr) if (nr >= 3) EXEC_STAT_IN_LOOP(body3); - SET_BRK_CURR_STAT( stat ); - + // HACK: point current "statement" at the condition expression, so + // that if there is an error in it, it resp. its location is printed, + // not the whole loop statement. + SET_BRK_CALL_TO(cond); } /* return 0 (to indicate that no leave-statement was executed) */ @@ -759,7 +763,6 @@ static ALWAYS_INLINE UInt ExecRepeatHelper(Stat stat, UInt nr) body3 = ADDR_STAT(stat)[3]; /* execute the body until the condition evaluates to 'true' */ - SET_BRK_CURR_STAT( stat ); do { #if !defined(HAVE_SIGNAL) @@ -776,7 +779,10 @@ static ALWAYS_INLINE UInt ExecRepeatHelper(Stat stat, UInt nr) if (nr >= 3) EXEC_STAT_IN_LOOP(body3); - SET_BRK_CURR_STAT( stat ); + // HACK: point current "statement" at the condition expression, so + // that if there is an error in it, it resp. its location is printed, + // not the whole loop statement. + SET_BRK_CALL_TO(cond); } while ( EVAL_BOOL_EXPR( cond ) == False ); @@ -931,7 +937,10 @@ UInt ExecAssert2Args ( "you may 'return true;' or 'return false;'"); } if ( decision == False ) { - SET_BRK_CURR_STAT( stat ); + // make sure the error back trace prints again at the statement, + // not any subexpression + SET_BRK_CALL_TO( stat ); + ErrorReturnVoid( "Assertion failure", 0L, 0L, "you may 'return;'"); } @@ -971,6 +980,7 @@ UInt ExecAssert3Args ( if ( decision == False ) { message = EVAL_EXPR(ADDR_STAT( stat )[2]); if ( message != (Obj) 0 ) { + SET_BRK_CALL_TO( stat ); if (IS_STRING_REP( message )) PrintString1( message ); else diff --git a/tst/test-error/backtrace.g b/tst/test-error/backtrace.g new file mode 100644 index 0000000000..0b9739bc6c --- /dev/null +++ b/tst/test-error/backtrace.g @@ -0,0 +1,20 @@ +f := function() + local l; + l := 0 * [1..6]; + l[[1..3]] := 1; +end; +f(); +Where(); +quit; + + +f:=function() if true = 1/0 then return 1; fi; return 2; end;; +f(); +Where(); +quit; + + +f:=function() if 1 then return 1; fi; return 2; end;; +f(); +Where(); +quit; diff --git a/tst/test-error/backtrace.g.out b/tst/test-error/backtrace.g.out new file mode 100644 index 0000000000..17be8c9b37 --- /dev/null +++ b/tst/test-error/backtrace.g.out @@ -0,0 +1,32 @@ +gap> f := function() +> local l; +> l := 0 * [1..6]; +> l[[1..3]] := 1; +> end; +function( ) ... end +gap> f(); +Error, no method found! For debugging hints type ?Recovery from NoMethodFound +Error, no 1st choice method found for `[]:=' on 3 arguments at GAPROOT/lib/methsel2.g:250 called from +l[[ 1 .. 3 ]] := 1; at *stdin*:5 called from +( ) + called from read-eval loop at *stdin*:7 +type 'quit;' to quit to outer loop +brk> Where(); +l[[ 1 .. 3 ]] := 1; at *stdin*:5 called from +( ) + called from read-eval loop at *errin*:1 +brk> quit; +gap> +gap> +gap> f:=function() if true = 1/0 then return 1; fi; return 2; end;; +gap> f(); +Error, Rational operations: must not be zero in + 1 / 0 at *stdin*:9 called from +( ) + called from read-eval loop at *stdin*:10 +you can replace via 'return ;' +brk> Where(); +( ) + called from read-eval loop at *errin*:1 +brk> quit; +gap> QUIT; diff --git a/tst/test-error/bad-array-int-0.g.out b/tst/test-error/bad-array-int-0.g.out index c5ca3fbd32..dba95bc6cf 100644 --- a/tst/test-error/bad-array-int-0.g.out +++ b/tst/test-error/bad-array-int-0.g.out @@ -7,7 +7,7 @@ function( ) ... end gap> f(); Error, no method found! For debugging hints type ?Recovery from NoMethodFound Error, no 1st choice method found for `[]' on 2 arguments at GAPROOT/lib/methsel2.g:250 called from -l[0] at *stdin*:5 called from +return l[0]; at *stdin*:5 called from ( ) called from read-eval loop at *stdin*:7 type 'quit;' to quit to outer loop diff --git a/tst/test-error/bad-array-int-1.g.out b/tst/test-error/bad-array-int-1.g.out index 78718c95cf..026a7cf242 100644 --- a/tst/test-error/bad-array-int-1.g.out +++ b/tst/test-error/bad-array-int-1.g.out @@ -4,7 +4,7 @@ gap> f := function() function( ) ... end gap> f(); Error, List Element: must be a list (not a integer) in - 1[1] at *stdin*:3 called from + return 1[1]; at *stdin*:3 called from ( ) called from read-eval loop at *stdin*:5 you can replace via 'return ;' diff --git a/tst/test-error/bad-array-string.g.out b/tst/test-error/bad-array-string.g.out index 77bd95cebc..18c1377a63 100644 --- a/tst/test-error/bad-array-string.g.out +++ b/tst/test-error/bad-array-string.g.out @@ -5,7 +5,7 @@ function( ) ... end gap> f(); Error, no method found! For debugging hints type ?Recovery from NoMethodFound Error, no 1st choice method found for `[]' on 2 arguments at GAPROOT/lib/methsel2.g:250 called from -1["abc"] at *stdin*:3 called from +return 1["abc"]; at *stdin*:3 called from ( ) called from read-eval loop at *stdin*:5 type 'quit;' to quit to outer loop