ugh, signed >> on negative values is implementation-defined

(but, at least, not undefined, and usually right; regress-test for it)
This commit is contained in:
tg 2013-04-01 01:16:37 +00:00
parent d96c733069
commit 0f417614dd
2 changed files with 29 additions and 14 deletions

25
check.t
View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.603 2013/03/30 23:31:01 tg Exp $
# $MirOS: src/bin/mksh/check.t,v 1.604 2013/04/01 01:16:34 tg Exp $
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
@ -363,30 +363,32 @@ expected-stdout:
---
name: arith-mandatory
description:
If MKSH_GCC55009 is set when compiling, passing of
this test is *mandatory* for a valid mksh executable!
Passing of this test is *mandatory* for a valid mksh executable!
category: shell:legacy-no
stdin:
typeset -i sari=0
typeset -Ui uari=0
typeset -i x=0
print -r -- $((x++)):$sari=$uari.
print -r -- $((x++)):$sari=$uari. #0
let --sari --uari
print -r -- $((x++)):$sari=$uari.
print -r -- $((x++)):$sari=$uari. #1
sari=2147483647 uari=2147483647
print -r -- $((x++)):$sari=$uari.
print -r -- $((x++)):$sari=$uari. #2
let ++sari ++uari
print -r -- $((x++)):$sari=$uari.
print -r -- $((x++)):$sari=$uari. #3
let --sari --uari
let 'sari *= 2' 'uari *= 2'
let ++sari ++uari
print -r -- $((x++)):$sari=$uari.
print -r -- $((x++)):$sari=$uari. #4
let ++sari ++uari
print -r -- $((x++)):$sari=$uari.
print -r -- $((x++)):$sari=$uari. #5
sari=-2147483648 uari=-2147483648
print -r -- $((x++)):$sari=$uari.
print -r -- $((x++)):$sari=$uari. #6
let --sari --uari
print -r -- $((x++)):$sari=$uari.
print -r -- $((x++)):$sari=$uari. #7
(( sari = -5 >> 1 ))
((# uari = -5 >> 1 ))
print -r -- $((x++)):$sari=$uari. #8
expected-stdout:
0:0=0.
1:-1=4294967295.
@ -396,6 +398,7 @@ expected-stdout:
5:0=0.
6:-2147483648=2147483648.
7:2147483647=2147483647.
8:-3=2147483645.
---
name: arith-unsigned-1
description:

18
expr.c
View File

@ -23,7 +23,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.64 2013/04/01 01:02:09 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.65 2013/04/01 01:16:37 tg Exp $");
#if !HAVE_SILENT_IDIVWRAPV
#if !defined(MKSH_LEGACY_MODE) || HAVE_LONG_32BIT
@ -493,11 +493,23 @@ evalexpr(Expr_state *es, int prec)
break;
case O_RSHIFT:
case O_RSHIFTASN:
/* all bivui users need special handling */
res = bivui(vl, >>, vr);
if (es->natural)
res = vl->val.u >> vr->val.u;
else {
/*
* This is implementation-defined in ISO C,
* though not undefined, and all known twos
* complement implementations make an arith
* shift-right out of this, and open-coding
* it would probably hurt massively.
*/
/* how about ANDing? use vr->val.u? */
res = (mksh_uari_t)(vl->val.i >> vr->val.i);
}
break;
/* how about rotation? */
case O_LT:
/* all bivui users need special handling */
res = bivui(vl, <, vr);
break;
case O_LE: