Index: generic/itclMethod.c ================================================================== --- generic/itclMethod.c +++ generic/itclMethod.c @@ -2454,12 +2454,12 @@ } Itcl_PushStack(framePtr, stackPtr); if (ioPtr != NULL) { - ioPtr->callRefCount++; - Itcl_PreserveData(ioPtr); + ioPtr->callRefCount++; + Itcl_PreserveData(ioPtr); /* ++ preserve until ItclAfterCallMethod releases it */ } imPtr->iclsPtr->callRefCount++; if (!imPtr->iclsPtr->infoPtr->useOldResolvers) { Itcl_SetCallFrameResolver(interp, ioPtr->resolvePtr); } @@ -2569,15 +2569,18 @@ hPtr = Tcl_FindHashEntry(&callContextPtr->ioPtr->contextCache, (char *)callContextPtr->imPtr); if (hPtr == NULL) { ckfree((char *)callContextPtr); } - Itcl_ReleaseData(ioPtr); } else { ckfree((char *)callContextPtr); } } + + if (ioPtr != NULL) { + Itcl_ReleaseData(ioPtr); /* -- paired release for preserve in ItclCheckCallMethod */ + } result = call_result; finishReturn: Itcl_ReleaseData(imPtr); return result; } Index: tests/methods.test ================================================================== --- tests/methods.test +++ tests/methods.test @@ -151,10 +151,26 @@ LeakClass::leakProc ::itcl::delete class LeakClass } list 0 } 0 +test methods-2.2 {covers leak condition test for nested methods calls within eval, bug [8e632ce049]} -setup { + itcl::class C1 { + proc factory {} { + set obj [C1 #auto] + $obj myeval [list $obj read] + itcl::delete object $obj + } + method myeval {script} { eval $script } + method read {} { myeval {} } + } +} -body { + time { C1::factory } 50 + list 0 +} -result 0 -cleanup { + itcl::delete class C1 +} # ---------------------------------------------------------------------- # Clean up # ---------------------------------------------------------------------- itcl::delete class test_args