summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--Src/exec.c12
-rw-r--r--Test/C03traps.ztst16
3 files changed, 25 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index fdd9ac26c..215da1b19 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2022-12-03 Bart Schaefer <schaefer@zsh.org>
+ * Philippe Altherr: 51071: Src/exec.c, Test/C03traps.ztst: fix
+ ERR_RETURN when a function using && / || is called within another
+ statement using && / ||
+
* Philippe Altherr: 51001: Src/exec.c, Src/loop.c,
Test/C03traps.ztst: adjust handling of ERR_EXIT to more closely
align with POSIX and with other shells; add corresponding tests
diff --git a/Src/exec.c b/Src/exec.c
index 43df8211a..711d8f374 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -1427,14 +1427,12 @@ execlist(Estate state, int dont_change_job, int exiting)
goto sublist_done;
}
while (wc_code(code) == WC_SUBLIST) {
- int isend = (WC_SUBLIST_TYPE(code) == WC_SUBLIST_END);
+ int isandor = WC_SUBLIST_TYPE(code) != WC_SUBLIST_END;
+ int isnot = WC_SUBLIST_FLAGS(code) & WC_SUBLIST_NOT;
next = state->pc + WC_SUBLIST_SKIP(code);
- if (!oldnoerrexit)
- noerrexit = isend ? 0 : NOERREXIT_EXIT | NOERREXIT_RETURN;
- if (WC_SUBLIST_FLAGS(code) & WC_SUBLIST_NOT) {
- /* suppress errexit for the commands in ! <list-of-commands> */
+ /* suppress errexit for commands before && and || and after ! */
+ if (isandor || isnot)
noerrexit = NOERREXIT_EXIT | NOERREXIT_RETURN;
- }
switch (WC_SUBLIST_TYPE(code)) {
case WC_SUBLIST_END:
/* End of sublist; just execute, ignoring status. */
@@ -1444,7 +1442,7 @@ execlist(Estate state, int dont_change_job, int exiting)
execpline(state, code, ltype, (ltype & Z_END) && exiting);
state->pc = next;
/* suppress errexit for the command "! ..." */
- if (WC_SUBLIST_FLAGS(code) & WC_SUBLIST_NOT)
+ if (isnot)
this_noerrexit = 1;
goto sublist_done;
break;
diff --git a/Test/C03traps.ztst b/Test/C03traps.ztst
index a8880673f..b7132da81 100644
--- a/Test/C03traps.ztst
+++ b/Test/C03traps.ztst
@@ -670,6 +670,22 @@ F:Must be tested with a top-level script rather than source or function
>before-out
>before-in
+ (set -o err_return
+ fn() {
+ print before-in
+ { false; true } && true
+ print after-in
+ }
+ print before-out
+ fn && true
+ print after-out
+ )
+0:ERR_RETURN not triggered on LHS of "&&" in function on LHS of "&&" (regression test)
+>before-out
+>before-in
+>after-in
+>after-out
+
mkdir -p zdotdir
print >zdotdir/.zshenv '
setopt norcs errreturn