diff --git a/ChangeLog b/ChangeLog
index f7f97bc0f..16a937e50 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2016-10-13 Peter Stephenson
+
+ * 39625: Martijn Dekker: Src/loop.c, Test/A01grammar.ztst: case
+ needs to reset lastval if no pattern matched.
+
2016-10-13 Oliver Kiddle
* 39622: Test/Y03arguments.ztst: add test cases for recent
diff --git a/Src/loop.c b/Src/loop.c
index 94b61b7ed..b791a898d 100644
--- a/Src/loop.c
+++ b/Src/loop.c
@@ -584,7 +584,7 @@ execcase(Estate state, int do_exec)
Wordcode end, next;
wordcode code = state->pc[-1];
char *word, *pat;
- int npat, save, nalts, ialt, patok;
+ int npat, save, nalts, ialt, patok, anypatok;
Patprog *spprog, pprog;
end = state->pc + WC_CASE_SKIP(code);
@@ -592,6 +592,7 @@ execcase(Estate state, int do_exec)
word = ecgetstr(state, EC_DUP, NULL);
singsub(&word);
untokenize(word);
+ anypatok = 0;
cmdpush(CS_CASE);
while (state->pc < end) {
@@ -648,7 +649,7 @@ execcase(Estate state, int do_exec)
*spprog = pprog;
}
if (pprog && pattry(pprog, word))
- patok = 1;
+ patok = anypatok = 1;
state->pc += 2;
nalts--;
}
@@ -679,6 +680,9 @@ execcase(Estate state, int do_exec)
state->pc = end;
+ if (!anypatok)
+ lastval = 0;
+
return lastval;
}
diff --git a/Test/A01grammar.ztst b/Test/A01grammar.ztst
index 0e77f3ebc..e4b6870d7 100644
--- a/Test/A01grammar.ztst
+++ b/Test/A01grammar.ztst
@@ -763,6 +763,23 @@
;;
esac
0:case retains exit status for execution of cases
+>37
+
+ false
+ case stuff in
+ (nomatch) foo
+ ;;
+ esac
+ echo $?
+0:case sets exit status to zero if no patterns are matched
+>0
+
+ case match in
+ (match) true; false; (exit 37)
+ ;;
+ esac
+ echo $?
+0:case keeps exit status of last command executed in compound-list
>37
x=1