summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2006-03-25 16:58:38 (GMT)
committerdgp <dgp@users.sourceforge.net>2006-03-25 16:58:38 (GMT)
commit773e53fd316eb916b885120ed4960368abec9acd (patch)
tree194f24f0e654cc000fb057f5284f806d07634e7d
parentd6c8b1f344c1864f243a235fd35b19b5277c2d1f (diff)
downloadtcl-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--ChangeLog5
-rw-r--r--generic/tclExecute.c12
-rw-r--r--tests/expr.test3
3 files changed, 15 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 778ea4f..fe60ad1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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