Index: generic/tclVar.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclVar.c,v
retrieving revision 1.50
diff -u -r1.50 tclVar.c
--- generic/tclVar.c	20 Mar 2002 22:47:36 -0000	1.50
+++ generic/tclVar.c	27 Mar 2002 22:30:38 -0000
@@ -40,14 +40,16 @@
  * Forward references to procedures defined later in this file:
  */
 
-static  char *		CallTraces _ANSI_ARGS_((Interp *iPtr, Var *arrayPtr,
+static int		CallTraces _ANSI_ARGS_((Interp *iPtr, Var *arrayPtr,
 			    Var *varPtr, char *part1, CONST char *part2,
-			    int flags, int *resultTypePtr));
+			    int flags, int leaveErrMsg));
 static void		CleanupVar _ANSI_ARGS_((Var *varPtr,
 			    Var *arrayPtr));
 static void		DeleteSearches _ANSI_ARGS_((Var *arrayVarPtr));
 static void		DeleteArray _ANSI_ARGS_((Interp *iPtr,
 			    char *arrayName, Var *varPtr, int flags));
+static void		DisposeTraceResult _ANSI_ARGS_((int flags,
+			    char *result));
 static int		MakeUpvar _ANSI_ARGS_((
 			    Interp *iPtr, CallFrame *framePtr,
 			    char *otherP1, CONST char *otherP2, int otherFlags,
@@ -634,24 +636,9 @@
 
     if ((varPtr->tracePtr != NULL)
 	    || ((arrayPtr != NULL) && (arrayPtr->tracePtr != NULL))) {
-	int resultType;
-	msg = CallTraces(iPtr, arrayPtr, varPtr, part1, part2,
-		(flags & (TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY)) | TCL_TRACE_READS,
-		&resultType);
-	if (msg != NULL) {
-	    if (flags & TCL_LEAVE_ERR_MSG) {
-		if (resultType & TCL_TRACE_RESULT_OBJECT) {
-		    VarErrMsg(interp, part1, part2, "read",
-			      Tcl_GetString((Tcl_Obj *) msg));
-		} else {
-		    VarErrMsg(interp, part1, part2, "read", msg);
-		}
-	    }
-	    if (resultType & TCL_TRACE_RESULT_DYNAMIC) {
-		ckfree(msg);
-	    } else if (resultType & TCL_TRACE_RESULT_OBJECT) {
-		Tcl_DecrRefCount((Tcl_Obj *) msg);
-	    }
+	if (TCL_ERROR == CallTraces(iPtr, arrayPtr, varPtr, part1, part2,
+		(flags & (TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY))
+		| TCL_TRACE_READS, (flags & TCL_LEAVE_ERR_MSG))) {
 	    goto errorReturn;
 	}
     }
@@ -770,24 +757,8 @@
      */
 
     if (varPtr->tracePtr != NULL) {
-	int resultType;
-
-	msg = CallTraces(iPtr, /*arrayPtr*/ NULL, varPtr, varName, NULL,
-		TCL_TRACE_READS, &resultType);
-	if (msg != NULL) {
-	    if (flags & TCL_LEAVE_ERR_MSG) {
-		if (resultType & TCL_TRACE_RESULT_OBJECT) {
-		    VarErrMsg(interp, varName, NULL, "read",
-			      Tcl_GetString((Tcl_Obj *) msg));
-		} else {
-		    VarErrMsg(interp, varName, NULL, "read", msg);
-		}
-	    }
-	    if (resultType & TCL_TRACE_RESULT_DYNAMIC) {
-		ckfree(msg);
-	    } else if (resultType & TCL_TRACE_RESULT_OBJECT) {
-		Tcl_DecrRefCount((Tcl_Obj *) msg);
-	    }
+	if (TCL_ERROR == CallTraces(iPtr, /*arrayPtr*/ NULL, varPtr, varName,
+		NULL, TCL_TRACE_READS, (flags & TCL_LEAVE_ERR_MSG))) {
 	    return NULL;
 	}
     }
@@ -939,24 +910,8 @@
 
     if ((varPtr->tracePtr != NULL)
             || ((arrayPtr != NULL) && (arrayPtr->tracePtr != NULL))) {
-	int resultType;
-
-	msg = CallTraces(iPtr, arrayPtr, varPtr, arrayName, elem,
-	        TCL_TRACE_READS, &resultType);
-	if (msg != NULL) {
-	    if (flags & TCL_LEAVE_ERR_MSG) {
-		if (resultType & TCL_TRACE_RESULT_OBJECT) {
-		    VarErrMsg(interp, arrayName, elem, "read",
-			      Tcl_GetString((Tcl_Obj *) msg));
-		} else {
-		    VarErrMsg(interp, arrayName, elem, "read", msg);
-		}
-	    }
-	    if (resultType & TCL_TRACE_RESULT_DYNAMIC) {
-		ckfree(msg);
-	    } else if (resultType & TCL_TRACE_RESULT_OBJECT) {
-		Tcl_DecrRefCount((Tcl_Obj *)msg);
-	    }
+	if (TCL_ERROR == CallTraces(iPtr, arrayPtr, varPtr, arrayName, elem,
+	        TCL_TRACE_READS, (flags & TCL_LEAVE_ERR_MSG))) {
 	    goto errorReturn;
 	}
     }
@@ -1367,25 +1322,9 @@
 
     if ((varPtr->tracePtr != NULL)
 	    || ((arrayPtr != NULL) && (arrayPtr->tracePtr != NULL))) {
-	int resultType;
-
-	char *msg = CallTraces(iPtr, arrayPtr, varPtr, part1, part2,
-	        (flags & (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY)) | TCL_TRACE_WRITES,
-		&resultType);
-	if (msg != NULL) {
-	    if (flags & TCL_LEAVE_ERR_MSG) {
-		if (resultType & TCL_TRACE_RESULT_OBJECT) {
-		    VarErrMsg(interp, part1, part2, "set",
-			      Tcl_GetString((Tcl_Obj *) msg));
-		} else {
-		    VarErrMsg(interp, part1, part2, "set", msg);
-		}
-	    }
-	    if (resultType & TCL_TRACE_RESULT_DYNAMIC) {
-		ckfree(msg);
-	    } else if (resultType & TCL_TRACE_RESULT_OBJECT) {
-		Tcl_DecrRefCount((Tcl_Obj *)msg);
-	    }
+	if (TCL_ERROR == CallTraces(iPtr, arrayPtr, varPtr, part1, part2,
+	        (flags & (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY))
+		| TCL_TRACE_WRITES, (flags & TCL_LEAVE_ERR_MSG))) {
 	    goto cleanup;
 	}
     }
@@ -1515,24 +1454,8 @@
 
     if ((flags & TCL_APPEND_VALUE) && (flags & TCL_LIST_ELEMENT)
 	    && (varPtr->tracePtr != NULL)) {
-	int resultType;
-
-	char *msg = CallTraces(iPtr, /*arrayPtr*/ NULL, varPtr, varName, NULL,
-		TCL_TRACE_READS, &resultType);
-	if (msg != NULL) {
-	    if (flags & TCL_LEAVE_ERR_MSG) {
-		if (resultType & TCL_TRACE_RESULT_OBJECT) {
-		    VarErrMsg(interp, varName, NULL, "read",
-			      Tcl_GetString((Tcl_Obj *) msg));
-		} else {
-		    VarErrMsg(interp, varName, NULL, "read", msg);
-		}
-	    }
-	    if (resultType & TCL_TRACE_RESULT_DYNAMIC) {
-		ckfree(msg);
-	    } else if (resultType & TCL_TRACE_RESULT_OBJECT) {
-		Tcl_DecrRefCount((Tcl_Obj *)msg);
-	    }
+	if (TCL_ERROR == CallTraces(iPtr, /*arrayPtr*/ NULL, varPtr, varName,
+		NULL, TCL_TRACE_READS, (flags & TCL_LEAVE_ERR_MSG))) {
 	    return NULL;
 	}
     }
@@ -1631,24 +1554,8 @@
      */
 
     if (varPtr->tracePtr != NULL) {
-	int resultType;
-
-	char *msg = CallTraces(iPtr, /*arrayPtr*/ NULL, varPtr,
-	        varName, (char *) NULL, TCL_TRACE_WRITES, &resultType);
-	if (msg != NULL) {
-	    if (flags & TCL_LEAVE_ERR_MSG) {
-		if (resultType & TCL_TRACE_RESULT_OBJECT) {
-		    VarErrMsg(interp, varName, NULL, "set",
-			      Tcl_GetString((Tcl_Obj *) msg));
-		} else {
-		    VarErrMsg(interp, varName, NULL, "set", msg);
-		}
-	    }
-	    if (resultType & TCL_TRACE_RESULT_DYNAMIC) {
-		ckfree(msg);
-	    } else if (resultType & TCL_TRACE_RESULT_OBJECT) {
-		Tcl_DecrRefCount((Tcl_Obj *)msg);
-	    }
+	if (TCL_ERROR == CallTraces(iPtr, /*arrayPtr*/ NULL, varPtr, varName,
+		NULL, TCL_TRACE_WRITES, (flags & TCL_LEAVE_ERR_MSG))) {
 	    goto cleanup;
 	}
     }
@@ -1849,24 +1756,8 @@
     if ((flags & TCL_APPEND_VALUE) && (flags & TCL_LIST_ELEMENT)
 	    && ((varPtr->tracePtr != NULL)
 		    || ((arrayPtr != NULL) && (arrayPtr->tracePtr != NULL)))) {
-	int resultType;
-
-	char *msg = CallTraces(iPtr, arrayPtr, varPtr, arrayName, elem,
-		TCL_TRACE_READS, &resultType);
-	if (msg != NULL) {
-	    if (flags & TCL_LEAVE_ERR_MSG) {
-		if (resultType & TCL_TRACE_RESULT_OBJECT) {
-		    VarErrMsg(interp, arrayName, elem, "read",
-			      Tcl_GetString((Tcl_Obj *) msg));
-		} else {
-		    VarErrMsg(interp, arrayName, elem, "read", msg);
-		}
-	    }
-	    if (resultType & TCL_TRACE_RESULT_DYNAMIC) {
-		ckfree(msg);
-	    } else if (resultType & TCL_TRACE_RESULT_OBJECT) {
-		Tcl_DecrRefCount((Tcl_Obj *) msg);
-	    }
+	if (TCL_ERROR == CallTraces(iPtr, arrayPtr, varPtr, arrayName, elem,
+		TCL_TRACE_READS, (flags & TCL_LEAVE_ERR_MSG))) {
 	    goto errorReturn;
 	}
     }
@@ -1936,24 +1827,8 @@
 
     if ((varPtr->tracePtr != NULL)
 	    || ((arrayPtr != NULL) && (arrayPtr->tracePtr != NULL))) {
-	int resultType;
-
-	char *msg = CallTraces(iPtr, arrayPtr, varPtr, arrayName, elem,
-		TCL_TRACE_WRITES, &resultType);
-	if (msg != NULL) {
-	    if (flags & TCL_LEAVE_ERR_MSG) {
-		if (resultType & TCL_TRACE_RESULT_OBJECT) {
-		    VarErrMsg(interp, arrayName, elem, "set",
-			      Tcl_GetString((Tcl_Obj *) msg));
-		} else {
-		    VarErrMsg(interp, arrayName, elem, "set", msg);
-		}
-	    }
-	    if (resultType & TCL_TRACE_RESULT_DYNAMIC) {
-		ckfree(msg);
-	    } else if (resultType & TCL_TRACE_RESULT_OBJECT) {
-		Tcl_DecrRefCount((Tcl_Obj *) msg);
-	    }
+	if (TCL_ERROR == CallTraces(iPtr, arrayPtr, varPtr, arrayName, elem,
+		TCL_TRACE_WRITES, (flags & TCL_LEAVE_ERR_MSG))) {
 	    goto errorReturn;
 	}
     }
@@ -2416,21 +2291,11 @@
 
     if ((dummyVar.tracePtr != NULL)
 	    || ((arrayPtr != NULL) && (arrayPtr->tracePtr != NULL))) {
-	char *msg;
-	int resultType;
-
 	varPtr->refCount++;
 	dummyVar.flags &= ~VAR_TRACE_ACTIVE;
-	msg = CallTraces(iPtr, arrayPtr, &dummyVar, part1, part2,
-		(flags & (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY)) | TCL_TRACE_UNSETS,
-		&resultType);
-	if (msg != NULL) {
-	    if (resultType & TCL_TRACE_RESULT_DYNAMIC) {
-		ckfree(msg);
-	    } else if (resultType & TCL_TRACE_RESULT_OBJECT) {
-		Tcl_DecrRefCount((Tcl_Obj *) msg);
-	    }
-	}
+	CallTraces(iPtr, arrayPtr, &dummyVar, part1, part2,
+		(flags & (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY))
+		| TCL_TRACE_UNSETS, /* leaveErrMsg */ 0);
 	while (dummyVar.tracePtr != NULL) {
 	    VarTrace *tracePtr = dummyVar.tracePtr;
 	    dummyVar.tracePtr = tracePtr->nextPtr;
@@ -3251,22 +3116,9 @@
 
     if (varPtr != NULL && varPtr->tracePtr != NULL
 	    && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
-	int resultType;
-
-	msg = CallTraces(iPtr, arrayPtr, varPtr, varName, NULL,
+	if (TCL_ERROR == CallTraces(iPtr, arrayPtr, varPtr, varName, NULL,
 		(TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
-		TCL_TRACE_ARRAY), &resultType);
-	if (msg != NULL) {
-	    if (resultType & TCL_TRACE_RESULT_DYNAMIC) {
-		VarErrMsg(interp, varName, NULL, "trace array", msg);
-		ckfree(msg);
-	    } else if (resultType & TCL_TRACE_RESULT_OBJECT) {
-		VarErrMsg(interp, varName, NULL, "trace array",
-			  Tcl_GetString((Tcl_Obj *) msg));
-		Tcl_DecrRefCount((Tcl_Obj *)msg);
-	    } else {
-		VarErrMsg(interp, varName, NULL, "trace array", msg);
-	    }
+		TCL_TRACE_ARRAY), /* leaveErrMsg */ 1)) {
 	    return TCL_ERROR;
 	}
     }
@@ -4519,6 +4371,38 @@
 /*
  *----------------------------------------------------------------------
  *
+ * DisposeTraceResult--
+ *
+ *	This procedure is called to dispose of the result returned from
+ *	a trace procedure.  The disposal method appropriate to the type
+ *	of result is determined by flags.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The memory allocated for the trace result may be freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+DisposeTraceResult(flags, result)
+    int flags;			/* Indicates type of result to determine
+				 * proper disposal method */
+    char *result;		/* The result returned from a trace
+				 * procedure to be disposed */
+{
+    if (flags & TCL_TRACE_RESULT_DYNAMIC) {
+	ckfree(result);
+    } else if (flags & TCL_TRACE_RESULT_OBJECT) {
+	Tcl_DecrRefCount((Tcl_Obj *) result);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
  * CallTraces --
  *
  *	This procedure is invoked to find and invoke relevant
@@ -4527,12 +4411,11 @@
  *	variable and on its containing array (where relevant).
  *
  * Results:
- *	The return value is NULL if no trace procedures were invoked, or
- *	if all the invoked trace procedures returned successfully.
- *	The return value is non-NULL if a trace procedure returned an
- *	error (in this case no more trace procedures were invoked after
- *	the error was returned). In this case the return value is a
- *	pointer to a static string describing the error.
+ *      Returns TCL_OK to indicate normal operation.  Returns TCL_ERROR
+ *      if invocation of a trace procedure indicated an error.  When
+ *      TCL_ERROR is returned and leaveErrMsg is true, then the
+ *      ::errorInfo variable of iPtr has information about the error
+ *      appended to it.
  *
  * Side effects:
  *	Almost anything can happen, depending on trace; this procedure
@@ -4541,8 +4424,8 @@
  *----------------------------------------------------------------------
  */
 
-static char *
-CallTraces(iPtr, arrayPtr, varPtr, part1, part2, flags, resultTypePtr)
+int 
+CallTraces(iPtr, arrayPtr, varPtr, part1, part2, flags, leaveErrMsg)
     Interp *iPtr;		/* Interpreter containing variable. */
     register Var *arrayPtr;	/* Pointer to array variable that contains
 				 * the variable, or NULL if the variable
@@ -4556,7 +4439,7 @@
 				 * plus other stuff like TCL_GLOBAL_ONLY,
 				 * TCL_NAMESPACE_ONLY, and
 				 * TCL_INTERP_DESTROYED. */
-    int *resultTypePtr;		/* Report what kind of result was generated
+    int leaveErrMsg;		/* Report what kind of result was generated
 				 * from the trace to this location. */
 {
     register VarTrace *tracePtr;
@@ -4564,6 +4447,8 @@
     char *result, *openParen, *p;
     Tcl_DString nameCopy;
     int copiedName;
+    int code = TCL_OK;
+    int disposeFlags = 0;
 
     /*
      * If there are already similar trace procedures active for the
@@ -4571,7 +4456,7 @@
      */
 
     if (varPtr->flags & VAR_TRACE_ACTIVE) {
-	return NULL;
+	return code;
     }
     varPtr->flags |= VAR_TRACE_ACTIVE;
     varPtr->refCount++;
@@ -4631,21 +4516,18 @@
 	    result = (*tracePtr->traceProc)(tracePtr->clientData,
 		    (Tcl_Interp *) iPtr, part1, part2, flags);
 	    if (result != NULL) {
-		*resultTypePtr = tracePtr->flags &
-			(TCL_TRACE_RESULT_DYNAMIC | TCL_TRACE_RESULT_OBJECT);
 		if (flags & TCL_TRACE_UNSETS) {
-		    if (tracePtr->flags & TCL_TRACE_RESULT_DYNAMIC) {
-			ckfree(result);
-		    } else if (tracePtr->flags & TCL_TRACE_RESULT_OBJECT) {
-			Tcl_DecrRefCount((Tcl_Obj *) result);
-		    }
-		    result = NULL;
+		    /* Ignore errors in unset traces */
+		    DisposeTraceResult(tracePtr->flags, result);
 		} else {
-	            Tcl_Release((ClientData) tracePtr);
-		    goto done;
+	            disposeFlags = tracePtr->flags;
+		    code = TCL_ERROR;
 		}
 	    }
 	    Tcl_Release((ClientData) tracePtr);
+	    if (code == TCL_ERROR) {
+		goto done;
+	    }
 	}
     }
 
@@ -4667,21 +4549,18 @@
 	result = (*tracePtr->traceProc)(tracePtr->clientData,
 		(Tcl_Interp *) iPtr, part1, part2, flags);
 	if (result != NULL) {
-	    *resultTypePtr = tracePtr->flags &
-		    (TCL_TRACE_RESULT_DYNAMIC | TCL_TRACE_RESULT_OBJECT);
 	    if (flags & TCL_TRACE_UNSETS) {
-		if (tracePtr->flags & TCL_TRACE_RESULT_DYNAMIC) {
-		    ckfree(result);
-		} else if (tracePtr->flags & TCL_TRACE_RESULT_OBJECT) {
-		    Tcl_DecrRefCount((Tcl_Obj *) result);
-		}
-		result = NULL;
+		/* Ignore errors in unset traces */
+		DisposeTraceResult(tracePtr->flags, result);
 	    } else {
-	        Tcl_Release((ClientData) tracePtr);
-		goto done;
+		disposeFlags = tracePtr->flags;
+		code = TCL_ERROR;
 	    }
 	}
 	Tcl_Release((ClientData) tracePtr);
+	if (code == TCL_ERROR) {
+	    goto done;
+	}
     }
 
     /*
@@ -4690,6 +4569,33 @@
      */
 
     done:
+    if (code == TCL_ERROR) {
+	if (leaveErrMsg) {
+	    char *type = "";
+	    switch (flags&(TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_ARRAY)) {
+		case TCL_TRACE_READS: {
+		    type = "read";
+		    break;
+		}
+		case TCL_TRACE_WRITES: {
+		    type = "set";
+		    break;
+		}
+		case TCL_TRACE_ARRAY: {
+		    type = "trace array";
+		    break;
+		}
+	    }
+	    if (disposeFlags & TCL_TRACE_RESULT_OBJECT) {
+		VarErrMsg((Tcl_Interp *) iPtr, part1, part2, type,
+			Tcl_GetString((Tcl_Obj *) result));
+	    } else {
+		VarErrMsg((Tcl_Interp *) iPtr, part1, part2, type, result);
+	    }
+	}
+	DisposeTraceResult(disposeFlags,result);
+    }
+
     if (arrayPtr != NULL) {
 	arrayPtr->refCount--;
     }
@@ -4700,7 +4606,7 @@
     varPtr->refCount--;
     iPtr->activeTracePtr = active.nextPtr;
     Tcl_Release((ClientData) iPtr);
-    return result;
+    return code;
 }
 
 /*
@@ -5004,21 +4910,11 @@
 	 */
 
 	if (varPtr->tracePtr != NULL) {
-	    char *msg;
-	    int resultType;
-
 	    objPtr = Tcl_NewObj();
 	    Tcl_IncrRefCount(objPtr); /* until done with traces */
 	    Tcl_GetVariableFullName(interp, (Tcl_Var) varPtr, objPtr);
-	    msg = CallTraces(iPtr, (Var *) NULL, varPtr,
-		    Tcl_GetString(objPtr), (char *) NULL, flags, &resultType);
-	    if (msg != NULL) {
-		if (resultType & TCL_TRACE_RESULT_DYNAMIC) {
-		    ckfree(msg);
-		} else if (resultType & TCL_TRACE_RESULT_OBJECT) {
-		    Tcl_DecrRefCount((Tcl_Obj *) msg);
-		}
-	    }
+	    CallTraces(iPtr, (Var *) NULL, varPtr, Tcl_GetString(objPtr),
+		    NULL, flags, /* leaveErrMsg */ 0);
 	    Tcl_DecrRefCount(objPtr); /* free no longer needed obj */
 
 	    while (varPtr->tracePtr != NULL) {
@@ -5143,18 +5039,8 @@
 	 */
 
 	if (varPtr->tracePtr != NULL) {
-	    char *msg;
-	    int resultType;
-
-	    msg = CallTraces(iPtr, (Var *) NULL, varPtr,
-		    varPtr->name, (char *) NULL, flags, &resultType);
-	    if (msg != NULL) {
-		if (resultType & TCL_TRACE_RESULT_DYNAMIC) {
-		    ckfree(msg);
-		} else if (resultType & TCL_TRACE_RESULT_OBJECT) {
-		    Tcl_DecrRefCount((Tcl_Obj *) msg);
-		}
-	    }
+	    CallTraces(iPtr, (Var *) NULL, varPtr, varPtr->name, NULL,
+		    flags, /* leaveErrMsg */ 0);
 	    while (varPtr->tracePtr != NULL) {
 		VarTrace *tracePtr = varPtr->tracePtr;
 		varPtr->tracePtr = tracePtr->nextPtr;
@@ -5240,20 +5126,10 @@
 	}
 	elPtr->hPtr = NULL;
 	if (elPtr->tracePtr != NULL) {
-	    char *msg;
-	    int resultType;
-
 	    elPtr->flags &= ~VAR_TRACE_ACTIVE;
-	    msg = CallTraces(iPtr, (Var *) NULL, elPtr, arrayName,
+	    CallTraces(iPtr, (Var *) NULL, elPtr, arrayName,
 		    Tcl_GetHashKey(varPtr->value.tablePtr, hPtr), flags,
-		    &resultType);
-	    if (msg != NULL) {
-		if (resultType & TCL_TRACE_RESULT_DYNAMIC) {
-		    ckfree(msg);
-		} else if (resultType & TCL_TRACE_RESULT_OBJECT) {
-		    Tcl_DecrRefCount((Tcl_Obj *) msg);
-		}
-	    }
+		    /* leaveErrMsg */ 0);
 	    while (elPtr->tracePtr != NULL) {
 		VarTrace *tracePtr = elPtr->tracePtr;
 		elPtr->tracePtr = tracePtr->nextPtr;
@@ -5408,18 +5284,8 @@
 
     if ((varPtr->tracePtr != NULL)
 	    || ((arrayPtr != NULL) && (arrayPtr->tracePtr != NULL))) {
-	char *msg;
-	int resultType;
-
-	msg = CallTraces((Interp *)interp, arrayPtr, varPtr, varName,
-		(char *) NULL, TCL_TRACE_READS, &resultType);
-	if (msg != NULL) {
-	    if (resultType & TCL_TRACE_RESULT_DYNAMIC) {
-		ckfree(msg);
-	    } else if (resultType & TCL_TRACE_RESULT_OBJECT) {
-		Tcl_DecrRefCount((Tcl_Obj *) msg);
-	    }
-	}
+	CallTraces((Interp *)interp, arrayPtr, varPtr, varName, NULL,
+		TCL_TRACE_READS, /* leaveErrMsg */ 0);
     }
 
     /*
