summaryrefslogtreecommitdiffstats
path: root/generic/tclExecute.c
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2004-11-02 15:46:34 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2004-11-02 15:46:34 (GMT)
commit22950832b701d9cbc8f109de3cf39f70fe4745b3 (patch)
tree229d3ffdede731051c5cd946a2846daae9122c7e /generic/tclExecute.c
parent70638824c45321f58b781d0cd062c035a9656ee3 (diff)
downloadtcl-22950832b701d9cbc8f109de3cf39f70fe4745b3.zip
tcl-22950832b701d9cbc8f109de3cf39f70fe4745b3.tar.gz
tcl-22950832b701d9cbc8f109de3cf39f70fe4745b3.tar.bz2
Final fix for NaN != NaN bug. Thanks to Miguel Sofer for his improved patch.
[Bug 761471]
Diffstat (limited to 'generic/tclExecute.c')
-rw-r--r--generic/tclExecute.c67
1 files changed, 54 insertions, 13 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index ef4f379..04862e4 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.9 2004/09/18 19:17:12 dkf Exp $
+ * RCS: @(#) $Id: tclExecute.c,v 1.94.2.10 2004/11/02 15:46:35 dkf Exp $
*/
#include "tclInt.h"
@@ -2719,26 +2719,67 @@ TclExecuteByteCode(interp, codePtr)
value2Ptr = stackPtr[stackTop];
valuePtr = stackPtr[stackTop - 1];
+ /*
+ * Be careful in the equal-object case; 'NaN' isn't supposed
+ * to be equal to even itself. [Bug 761471]
+ */
+
+ t1Ptr = valuePtr->typePtr;
if (valuePtr == value2Ptr) {
/*
- * Optimize the equal object case.
+ * If we are numeric already, we can proceed to the main
+ * equality check right now. Otherwise, we need to try to
+ * coerce to a numeric type so we can see if we've got a
+ * NaN but haven't parsed it as numeric.
*/
+ if (!IS_NUMERIC_TYPE(t1Ptr)) {
+ if (t1Ptr == &tclListType) {
+ int length;
+ /*
+ * Only a list of length 1 can be NaN or such
+ * things.
+ */
+ (void) Tcl_ListObjLength(NULL, valuePtr, &length);
+ if (length == 1) {
+ goto mustConvertForNaNCheck;
+ }
+ } else {
+ /*
+ * Too bad, we'll have to compute the string and
+ * try the conversion
+ */
+
+ mustConvertForNaNCheck:
+ s1 = Tcl_GetStringFromObj(valuePtr, &length);
+ if (TclLooksLikeInt(s1, length)) {
+ GET_WIDE_OR_INT(iResult, valuePtr, i, w);
+ } else {
+ (void) Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,
+ valuePtr, &d1);
+ }
+ t1Ptr = valuePtr->typePtr;
+ }
+ }
+
switch (*pc) {
- case INST_EQ:
- case INST_LE:
- case INST_GE:
- iResult = 1;
- break;
- case INST_NEQ:
- case INST_LT:
- case INST_GT:
- iResult = 0;
- break;
+ case INST_EQ:
+ case INST_LE:
+ case INST_GE:
+ iResult = !((t1Ptr == &tclDoubleType)
+ && IS_NAN(valuePtr->internalRep.doubleValue));
+ break;
+ case INST_LT:
+ case INST_GT:
+ iResult = 0;
+ break;
+ case INST_NEQ:
+ iResult = ((t1Ptr == &tclDoubleType)
+ && IS_NAN(valuePtr->internalRep.doubleValue));
+ break;
}
goto foundResult;
}
- t1Ptr = valuePtr->typePtr;
t2Ptr = value2Ptr->typePtr;
/*