fix lazy evaluation with side effects; spotted by ormaaj via IRC

This commit is contained in:
tg 2016-11-07 16:58:48 +00:00
parent 7fef6b129e
commit 5ee8ba10b3
4 changed files with 78 additions and 11 deletions

View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/Makefile,v 1.152 2016/08/25 16:21:30 tg Exp $
# $MirOS: src/bin/mksh/Makefile,v 1.153 2016/11/07 16:58:45 tg Exp $
#-
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012, 2013, 2014, 2015, 2016
@ -57,7 +57,7 @@ CPPFLAGS+= -DMKSH_ASSUME_UTF8 -DMKSH_DISABLE_DEPRECATED \
-DHAVE_SETGROUPS=1 -DHAVE_STRERROR=0 -DHAVE_STRSIGNAL=0 \
-DHAVE_STRLCPY=1 -DHAVE_FLOCK_DECL=1 -DHAVE_REVOKE_DECL=1 \
-DHAVE_SYS_ERRLIST_DECL=1 -DHAVE_SYS_SIGLIST_DECL=1 \
-DHAVE_PERSISTENT_HISTORY=1 -DMKSH_BUILD_R=531
-DHAVE_PERSISTENT_HISTORY=1 -DMKSH_BUILD_R=539
CPPFLAGS+= -D${${PROG:L}_tf:C/(Mir${MAN:E}{0,1}){2}/4/:S/x/mksh_BUILD/:U}
CPPFLAGS+= -I.
COPTS+= -std=c89 -Wall

62
check.t
View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.754 2016/10/02 22:21:43 tg Exp $
# $MirOS: src/bin/mksh/check.t,v 1.755 2016/11/07 16:58:45 tg Exp $
# -*- mode: sh -*-
#-
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
@ -30,7 +30,7 @@
# (2013/12/02 20:39:44) http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date
expected-stdout:
@(#)MIRBSD KSH R53 2016/10/02
@(#)MIRBSD KSH R53 2016/11/07
description:
Check version of shell.
stdin:
@ -39,7 +39,7 @@ name: KSH_VERSION
category: shell:legacy-no
---
expected-stdout:
@(#)LEGACY KSH R53 2016/10/02
@(#)LEGACY KSH R53 2016/11/07
description:
Check version of legacy shell.
stdin:
@ -340,6 +340,62 @@ expected-stdout:
2
0
---
name: arith-lazy-5-arr-n
description: Check lazy evaluation with side effects
stdin:
a=0; echo "$((0&&b[a++],a))"
expected-stdout:
0
---
name: arith-lazy-5-arr-p
description: Check lazy evaluation with side effects
stdin:
a=0; echo "$((0&&(b[a++]),a))"
expected-stdout:
0
---
name: arith-lazy-5-str-n
description: Check lazy evaluation with side effects
stdin:
a=0 b=a++; ((0&&b)); echo $a
expected-stdout:
0
---
name: arith-lazy-5-str-p
description: Check lazy evaluation with side effects
stdin:
a=0 b=a++; ((0&&(b))); echo $a
expected-stdout:
0
---
name: arith-lazy-5-tern-l-n
description: Check lazy evaluation with side effects
stdin:
a=0; echo "$((0?b[a++]:999,a))"
expected-stdout:
0
---
name: arith-lazy-5-tern-l-p
description: Check lazy evaluation with side effects
stdin:
a=0; echo "$((0?(b[a++]):999,a))"
expected-stdout:
0
---
name: arith-lazy-5-tern-r-n
description: Check lazy evaluation with side effects
stdin:
a=0; echo "$((1?999:b[a++],a))"
expected-stdout:
0
---
name: arith-lazy-5-tern-r-p
description: Check lazy evaluation with side effects
stdin:
a=0; echo "$((1?999:(b[a++]),a))"
expected-stdout:
0
---
name: arith-ternary-prec-1
description:
Check precedence of ternary operator vs assignment

17
expr.c
View File

@ -23,7 +23,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.89 2016/09/01 12:55:21 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.90 2016/11/07 16:58:48 tg Exp $");
#define EXPRTOK_DEFNS
#include "exprtok.h"
@ -326,7 +326,15 @@ evalexpr(Expr_state *es, unsigned int prec)
vl = evalexpr(es, prec - 1);
while ((int)(op = es->tok) >= (int)O_EQ && (int)op <= (int)O_COMMA &&
opprec[(int)op] == prec) {
exprtoken(es);
switch ((int)op) {
case O_TERN:
case O_LAND:
case O_LOR:
break;
default:
exprtoken(es);
}
vasn = vl;
if (op != O_ASN)
/* vl may not have a value yet */
@ -340,14 +348,15 @@ evalexpr(Expr_state *es, unsigned int prec)
if (!ev)
es->noassign++;
exprtoken(es);
vl = evalexpr(es, MAX_PREC);
if (!ev)
es->noassign--;
if (es->tok != CTERN)
evalerr(es, ET_STR, "missing :");
exprtoken(es);
if (ev)
es->noassign++;
exprtoken(es);
vr = evalexpr(es, P_TERN);
if (ev)
es->noassign--;
@ -502,6 +511,7 @@ evalexpr(Expr_state *es, unsigned int prec)
case O_LAND:
if (!t1)
es->noassign++;
exprtoken(es);
vr = intvar(es, evalexpr(es, prec - 1));
res = t1 && vr->val.u;
if (!t1)
@ -510,6 +520,7 @@ evalexpr(Expr_state *es, unsigned int prec)
case O_LOR:
if (t1)
es->noassign++;
exprtoken(es);
vr = intvar(es, evalexpr(es, prec - 1));
res = t1 || vr->val.u;
if (t1)

6
sh.h
View File

@ -175,9 +175,9 @@
#endif
#ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.789 2016/10/02 22:21:47 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.790 2016/11/07 16:58:48 tg Exp $");
#endif
#define MKSH_VERSION "R53 2016/10/02"
#define MKSH_VERSION "R53 2016/11/07"
/* arithmetic types: C implementation */
#if !HAVE_CAN_INTTYPES
@ -578,7 +578,7 @@ char *ucstrstr(char *, const char *);
#define mkssert(e) do { } while (/* CONSTCOND */ 0)
#endif
#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 531)
#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 539)
#error Must run Build.sh to compile this.
extern void thiswillneverbedefinedIhope(void);
int