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, # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012, 2013, 2014, 2015, 2016 # 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_SETGROUPS=1 -DHAVE_STRERROR=0 -DHAVE_STRSIGNAL=0 \
-DHAVE_STRLCPY=1 -DHAVE_FLOCK_DECL=1 -DHAVE_REVOKE_DECL=1 \ -DHAVE_STRLCPY=1 -DHAVE_FLOCK_DECL=1 -DHAVE_REVOKE_DECL=1 \
-DHAVE_SYS_ERRLIST_DECL=1 -DHAVE_SYS_SIGLIST_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+= -D${${PROG:L}_tf:C/(Mir${MAN:E}{0,1}){2}/4/:S/x/mksh_BUILD/:U}
CPPFLAGS+= -I. CPPFLAGS+= -I.
COPTS+= -std=c89 -Wall 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 -*- # -*- mode: sh -*-
#- #-
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 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 # (2013/12/02 20:39:44) http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date
expected-stdout: expected-stdout:
@(#)MIRBSD KSH R53 2016/10/02 @(#)MIRBSD KSH R53 2016/11/07
description: description:
Check version of shell. Check version of shell.
stdin: stdin:
@ -39,7 +39,7 @@ name: KSH_VERSION
category: shell:legacy-no category: shell:legacy-no
--- ---
expected-stdout: expected-stdout:
@(#)LEGACY KSH R53 2016/10/02 @(#)LEGACY KSH R53 2016/11/07
description: description:
Check version of legacy shell. Check version of legacy shell.
stdin: stdin:
@ -340,6 +340,62 @@ expected-stdout:
2 2
0 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 name: arith-ternary-prec-1
description: description:
Check precedence of ternary operator vs assignment Check precedence of ternary operator vs assignment

15
expr.c
View File

@ -23,7 +23,7 @@
#include "sh.h" #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 #define EXPRTOK_DEFNS
#include "exprtok.h" #include "exprtok.h"
@ -326,7 +326,15 @@ evalexpr(Expr_state *es, unsigned int prec)
vl = evalexpr(es, prec - 1); vl = evalexpr(es, prec - 1);
while ((int)(op = es->tok) >= (int)O_EQ && (int)op <= (int)O_COMMA && while ((int)(op = es->tok) >= (int)O_EQ && (int)op <= (int)O_COMMA &&
opprec[(int)op] == prec) { opprec[(int)op] == prec) {
switch ((int)op) {
case O_TERN:
case O_LAND:
case O_LOR:
break;
default:
exprtoken(es); exprtoken(es);
}
vasn = vl; vasn = vl;
if (op != O_ASN) if (op != O_ASN)
/* vl may not have a value yet */ /* vl may not have a value yet */
@ -340,14 +348,15 @@ evalexpr(Expr_state *es, unsigned int prec)
if (!ev) if (!ev)
es->noassign++; es->noassign++;
exprtoken(es);
vl = evalexpr(es, MAX_PREC); vl = evalexpr(es, MAX_PREC);
if (!ev) if (!ev)
es->noassign--; es->noassign--;
if (es->tok != CTERN) if (es->tok != CTERN)
evalerr(es, ET_STR, "missing :"); evalerr(es, ET_STR, "missing :");
exprtoken(es);
if (ev) if (ev)
es->noassign++; es->noassign++;
exprtoken(es);
vr = evalexpr(es, P_TERN); vr = evalexpr(es, P_TERN);
if (ev) if (ev)
es->noassign--; es->noassign--;
@ -502,6 +511,7 @@ evalexpr(Expr_state *es, unsigned int prec)
case O_LAND: case O_LAND:
if (!t1) if (!t1)
es->noassign++; es->noassign++;
exprtoken(es);
vr = intvar(es, evalexpr(es, prec - 1)); vr = intvar(es, evalexpr(es, prec - 1));
res = t1 && vr->val.u; res = t1 && vr->val.u;
if (!t1) if (!t1)
@ -510,6 +520,7 @@ evalexpr(Expr_state *es, unsigned int prec)
case O_LOR: case O_LOR:
if (t1) if (t1)
es->noassign++; es->noassign++;
exprtoken(es);
vr = intvar(es, evalexpr(es, prec - 1)); vr = intvar(es, evalexpr(es, prec - 1));
res = t1 || vr->val.u; res = t1 || vr->val.u;
if (t1) if (t1)

6
sh.h
View File

@ -175,9 +175,9 @@
#endif #endif
#ifdef EXTERN #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 #endif
#define MKSH_VERSION "R53 2016/10/02" #define MKSH_VERSION "R53 2016/11/07"
/* arithmetic types: C implementation */ /* arithmetic types: C implementation */
#if !HAVE_CAN_INTTYPES #if !HAVE_CAN_INTTYPES
@ -578,7 +578,7 @@ char *ucstrstr(char *, const char *);
#define mkssert(e) do { } while (/* CONSTCOND */ 0) #define mkssert(e) do { } while (/* CONSTCOND */ 0)
#endif #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. #error Must run Build.sh to compile this.
extern void thiswillneverbedefinedIhope(void); extern void thiswillneverbedefinedIhope(void);
int int