about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@zsh.org>2017-08-31 16:54:19 +0100
committerPeter Stephenson <pws@zsh.org>2017-08-31 16:54:19 +0100
commitebcea98eca33b8894d29545f1a46331d03f3913a (patch)
tree6b834b6b2ddc7ed63f947154c52d99bf648943a4
parent73514c40f68fd7f66b64317d6e26793d400414ac (diff)
downloadzsh-ebcea98eca33b8894d29545f1a46331d03f3913a.tar.gz
zsh-ebcea98eca33b8894d29545f1a46331d03f3913a.tar.xz
zsh-ebcea98eca33b8894d29545f1a46331d03f3913a.zip
Fix problem with ERR_RETURN.
It wasn't suppressed properly in the code following an if
in some circumstances, in particular in initialsation scripts
and also in a nested function where the caller had suppressed
it.
-rw-r--r--ChangeLog6
-rw-r--r--Src/loop.c7
-rw-r--r--Test/C03traps.ztst34
3 files changed, 43 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 6dcbdf530..8dddd7d55 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2017-08-31  Peter Stephenson  <p.stephenson@samsung.com>
+
+	* 41627: Src/loop.c, Test/C03traps.ztst: fix problem with
+	ERR_RETURN in initialisation scripts and also on nested
+	function involving ERR_RETURN suppression in the caller.
+
 2017-08-30  Daniel Shahaf  <d.s@daniel.shahaf.name>
 
 	* 41567: Completion/Unix/Command/_tmux: Complete detached
diff --git a/Src/loop.c b/Src/loop.c
index 4859c976b..40e3bcb34 100644
--- a/Src/loop.c
+++ b/Src/loop.c
@@ -541,8 +541,7 @@ execif(Estate state, int do_exec)
     olderrexit = noerrexit;
     end = state->pc + WC_IF_SKIP(code);
 
-    if (!noerrexit)
-	noerrexit = NOERREXIT_EXIT | NOERREXIT_RETURN;
+    noerrexit |= NOERREXIT_EXIT | NOERREXIT_RETURN;
     while (state->pc < end) {
 	code = *state->pc++;
 	if (wc_code(code) != WC_IF ||
@@ -570,9 +569,9 @@ execif(Estate state, int do_exec)
 	if (olderrexit)
 	    noerrexit = olderrexit;
 	else if (lastval)
-	    noerrexit = NOERREXIT_EXIT | NOERREXIT_RETURN | NOERREXIT_UNTIL_EXEC;
+	    noerrexit |= NOERREXIT_EXIT | NOERREXIT_RETURN | NOERREXIT_UNTIL_EXEC;
 	else
-	    noerrexit = 0;
+	    noerrexit &= ~ (NOERREXIT_EXIT | NOERREXIT_RETURN);
 	cmdpush(run == 2 ? CS_ELSE : (s ? CS_ELIFTHEN : CS_IFTHEN));
 	execlist(state, 1, do_exec);
 	cmdpop();
diff --git a/Test/C03traps.ztst b/Test/C03traps.ztst
index f8a12319a..f22962550 100644
--- a/Test/C03traps.ztst
+++ b/Test/C03traps.ztst
@@ -661,6 +661,40 @@ F:Must be tested with a top-level script rather than source or function
 >before-out
 >before-in
 
+  mkdir -p zdotdir
+  print >zdotdir/.zshenv '
+  setopt norcs errreturn
+  fn() {
+    if false; then
+      print Bad
+    else
+      print Good
+    fi
+    print Better
+  }
+  fn
+  print In .zshenv'
+  ZDOTDIR=$PWD/zdotdir $ZTST_testdir/../Src/zsh -c 'true'
+0:ERR_RETURN within initialisation code with special flags
+>Good
+>Better
+>In .zshenv
+
+  fn2() {
+    if false; then
+      print Bad
+    else
+      print Good
+    fi
+  }
+  fn() {
+    setopt err_return
+    fn2 || true
+  }
+  fn
+0:ERR_RETURN in "else" branch in nested function
+>Good
+
   (setopt err_exit
   for x in y; do
     false && true