summaryrefslogtreecommitdiffstats
path: root/generic/tclOOMethod.c
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2011-03-04 18:23:04 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2011-03-04 18:23:04 (GMT)
commit80a9e493176e81c6becbb1715367300d20208449 (patch)
treee559bae06f05082eaac70eca9e26bbcf2b9014fe /generic/tclOOMethod.c
parent6f017f71965cb7b4b9be15054f25c0936c3356a9 (diff)
downloadtcl-80a9e493176e81c6becbb1715367300d20208449.zip
tcl-80a9e493176e81c6becbb1715367300d20208449.tar.gz
tcl-80a9e493176e81c6becbb1715367300d20208449.tar.bz2
[Bug 3185009]: Keep references to resolved object variables so that an unset doesn't leave any dangling pointers for code to trip over.Bug_3185009
Diffstat (limited to 'generic/tclOOMethod.c')
-rw-r--r--generic/tclOOMethod.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/generic/tclOOMethod.c b/generic/tclOOMethod.c
index bb10ca5..2c8c5b9 100644
--- a/generic/tclOOMethod.c
+++ b/generic/tclOOMethod.c
@@ -1057,6 +1057,14 @@ ProcedureMethodCompiledVarConnect(
}
if (cacheIt) {
infoPtr->cachedObjectVar = TclVarHashGetValue(hPtr);
+
+ /*
+ * We must keep a reference to the variable so everything will
+ * continue to work correctly even if it is unset; being unset does
+ * not end the life of the variable at this level. [Bug 3185009]
+ */
+
+ VarHashRefCount(infoPtr->cachedObjectVar)++;
}
return TclVarHashGetValue(hPtr);
}
@@ -1067,6 +1075,14 @@ ProcedureMethodCompiledVarDelete(
{
OOResVarInfo *infoPtr = (OOResVarInfo *) rPtr;
+ /*
+ * Release the reference to the variable if we were holding it.
+ */
+
+ if (infoPtr->cachedObjectVar) {
+ VarHashRefCount(infoPtr->cachedObjectVar)--;
+ TclCleanupVar((Var *) infoPtr->cachedObjectVar, NULL);
+ }
Tcl_DecrRefCount(infoPtr->variableObj);
ckfree((char *) infoPtr);
}