diff options
author | dgp <dgp@users.sourceforge.net> | 2006-03-25 16:58:38 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2006-03-25 16:58:38 (GMT) |
commit | 773e53fd316eb916b885120ed4960368abec9acd (patch) | |
tree | 194f24f0e654cc000fb057f5284f806d07634e7d | |
parent | d6c8b1f344c1864f243a235fd35b19b5277c2d1f (diff) | |
download | tcl-773e53fd316eb916b885120ed4960368abec9acd.zip tcl-773e53fd316eb916b885120ed4960368abec9acd.tar.gz tcl-773e53fd316eb916b885120ed4960368abec9acd.tar.bz2 |
* generic/tclExecute.c: Corrections to INST_EXPON detection of
overflow to use mp_int calculations.
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | generic/tclExecute.c | 12 | ||||
-rw-r--r-- | tests/expr.test | 3 |
3 files changed, 15 insertions, 5 deletions
@@ -1,3 +1,8 @@ +2006-03-25 Don Porter <dgp@users.sourceforge.net> + + * generic/tclExecute.c: Corrections to INST_EXPON detection of + overflow to use mp_int calculations. + 2006-03-24 Kevin Kenny <kennykb@acm.org> * generic/tclExecute.c (TclExecuteByteCode): Added a couple diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 9b1f26e..65da821 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclExecute.c,v 1.231 2006/03/24 19:05:40 kennykb Exp $ + * RCS: @(#) $Id: tclExecute.c,v 1.232 2006/03/25 16:58:38 dgp Exp $ */ #include "tclInt.h" @@ -4715,7 +4715,8 @@ TclExecuteByteCode( wResult -= 1; } break; - case INST_EXPON: + case INST_EXPON: { + int wasNegative; if (w2 & 1) { wResult = w1; } else { @@ -4724,21 +4725,24 @@ TclExecuteByteCode( w1 *= w1; w2 /= 2; for (; w2>Tcl_LongAsWide(1) ; w1*=w1,w2/=2) { + wasNegative = (wResult < 0); if (w1 < 0) { goto overflow; } if (w2 & 1) { wResult *= w1; - if (wResult < 0) { + if (wasNegative != (wResult < 0)) { goto overflow; } } } + wasNegative = (wResult < 0); wResult *= w1; - if (wResult < 0) { + if (wasNegative != (wResult < 0)) { goto overflow; } break; + } default: /* Unused, here to silence compiler warning. */ wResult = 0; diff --git a/tests/expr.test b/tests/expr.test index f747f87..8f86e66 100644 --- a/tests/expr.test +++ b/tests/expr.test @@ -10,7 +10,7 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # -# RCS: @(#) $Id: expr.test,v 1.52 2006/03/24 18:20:37 dgp Exp $ +# RCS: @(#) $Id: expr.test,v 1.53 2006/03/25 16:58:38 dgp Exp $ if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2.1 @@ -1031,6 +1031,7 @@ test expr-23.38 {INST_EXPON: big integer} {expr {10**19}} 1[string repeat 0 19] test expr-23.39 {INST_EXPON: big integer} { expr 1[string repeat 0 30]**2 } 1[string repeat 0 60] +test expr-23.40 {INST_EXPON: overflow to big integer} {expr {(-10)**3}} -1000 # Some compilers get this wrong; ensure that we work around it correctly test expr-24.1 {expr edge cases; shifting} {expr int(5)>>32} 0 |