diff options
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tclExecute.c | 34 |
1 files changed, 29 insertions, 5 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c index ad06d99..06456d3 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.192 2005/06/20 23:10:24 dkf Exp $ + * RCS: @(#) $Id: tclExecute.c,v 1.193 2005/06/29 03:29:00 mdejong Exp $ */ #include "tclInt.h" @@ -4224,10 +4224,11 @@ TclExecuteByteCode(interp, codePtr) double d; int boolvar; long i; + int negate_value = 1; Tcl_WideInt w; Tcl_ObjType *tPtr; Tcl_Obj *valuePtr; - + valuePtr = *tosPtr; tPtr = valuePtr->typePtr; if (IS_INTEGER_TYPE(tPtr) @@ -4247,6 +4248,23 @@ TclExecuteByteCode(interp, codePtr) char *s = Tcl_GetStringFromObj(valuePtr, &length); if (TclLooksLikeInt(s, length)) { GET_WIDE_OR_INT(result, valuePtr, i, w); + + /* + * An integer was parsed. If parsing a literal that + * is the smallest long value, then it would have + * been promoted to a wide since it would not fit in + * a long type without the leading '-'. Convert + * back to the smallest possible long. + */ + + if ((result == TCL_OK) && + (*pc == INST_UMINUS) && + (valuePtr->typePtr == &tclWideIntType) && + (w == -Tcl_LongAsWide(LONG_MIN))) { + valuePtr->typePtr = &tclIntType; + valuePtr->internalRep.longValue = LONG_MIN; + negate_value = 0; + } } else { result = Tcl_GetDoubleFromObj(NULL, valuePtr, &d); } @@ -4270,11 +4288,14 @@ TclExecuteByteCode(interp, codePtr) */ if (tPtr == &tclIntType) { i = valuePtr->internalRep.longValue; - TclNewLongObj(objResultPtr, -i); + if (negate_value) { + i = -i; + } + TclNewLongObj(objResultPtr, i); TRACE_WITH_OBJ(("%ld => ", i), objResultPtr); } else if (tPtr == &tclWideIntType) { TclGetWide(w,valuePtr); - TclNewWideIntObj(objResultPtr, -w); + TclNewWideIntObj(objResultPtr, -w); TRACE_WITH_OBJ((LLD" => ", w), objResultPtr); } else { d = valuePtr->internalRep.doubleValue; @@ -4288,7 +4309,10 @@ TclExecuteByteCode(interp, codePtr) */ if (tPtr == &tclIntType) { i = valuePtr->internalRep.longValue; - TclSetLongObj(valuePtr, -i); + if (negate_value) { + i = -i; + } + TclSetLongObj(valuePtr, i); TRACE_WITH_OBJ(("%ld => ", i), valuePtr); } else if (tPtr == &tclWideIntType) { TclGetWide(w,valuePtr); |