summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin B Kenny <kennykb@acm.org>2005-08-05 19:19:01 (GMT)
committerKevin B Kenny <kennykb@acm.org>2005-08-05 19:19:01 (GMT)
commit67c0945cef73efba280dda5e10e75f8f740ca1ae (patch)
treed5cde9c6342d799dd709df022d80ecd665932579
parent2af5fccf013d0106280ab267b33a07945bcfb272 (diff)
downloadtcl-67c0945cef73efba280dda5e10e75f8f740ca1ae.zip
tcl-67c0945cef73efba280dda5e10e75f8f740ca1ae.tar.gz
tcl-67c0945cef73efba280dda5e10e75f8f740ca1ae.tar.bz2
fix abs(MIN_INT) [Bug 1241572]
-rw-r--r--ChangeLog7
-rw-r--r--generic/tclExecute.c18
-rw-r--r--tests/expr.test8
3 files changed, 28 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 6eacdf0..935d45d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2005-08-05 Kevin Kenny <kennykb@users.sourceforge.net>
+
+ * generic/tclExecute.c (TclExecuteByteCode): Fixed a corner case
+ * tests/expr.test (expr-38.1): where applying abs to
+ MIN_INT failed to promote the result to a wide integer.
+ [Bug #1241572]
+
2005-08-04 Don Porter <dgp@users.sourceforge.net>
* generic/tclObj.c: Simplified routines that manage the typeTable.
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 2809466..82aaf62 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -11,7 +11,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.94.2.12 2005/04/05 16:40:11 dgp Exp $
+ * RCS: @(#) $Id: tclExecute.c,v 1.94.2.13 2005/08/05 19:19:11 kennykb Exp $
*/
#include "tclInt.h"
@@ -5077,13 +5077,23 @@ ExprAbsFunc(interp, eePtr, clientData)
if (i < 0) {
iResult = -i;
if (iResult < 0) {
- Tcl_ResetResult(interp);
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "integer value too large to represent", -1);
+#ifdef TCL_WIDE_INT_IS_LONG
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "integer value too large to represent", -1));
Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW",
"integer value too large to represent", (char *) NULL);
result = TCL_ERROR;
goto done;
+#else
+ /*
+ * Special case: abs(MIN_INT) must promote to wide.
+ */
+
+ PUSH_OBJECT( Tcl_NewWideIntObj(-(Tcl_WideInt) i) );
+ result = TCL_OK;
+ goto done;
+#endif
+
}
} else {
iResult = i;
diff --git a/tests/expr.test b/tests/expr.test
index 6ba6732..b3707b8 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.17.2.4 2004/11/02 15:46:35 dkf Exp $
+# RCS: @(#) $Id: expr.test,v 1.17.2.5 2005/08/05 19:19:14 kennykb Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest
@@ -21,6 +21,7 @@ testConstraint registeredMathFuncs [expr {
([catch {expr T1()} msg] != 1) || ($msg ne {unknown math function "T1"})
}]
+testConstraint wideIs64bit [expr {(0x80000000 > 0) && (0x8000000000000000 < 0)}]
# procedures used below
proc put_hello_char {c} {
@@ -822,6 +823,11 @@ test expr-24.7 {expr edge cases; shifting} {expr wide(5)<<31} 10737418240
test expr-24.8 {expr edge cases; shifting} nonPortable {expr wide(5)<<63} -9223372036854775808
test expr-24.9 {expr edge cases; shifting} {expr 5>>32} 0
+test expr-38.1 {abs of smallest 32-bit integer [Bug 1241572]} {wideIs64bit} {
+ expr {abs(int(-2147483648))}
+} 2147483648
+
+
# cleanup
if {[info exists a]} {
unset a