Repository navigation
interfaced object nil leak
Alexander Liberov edited this page Nov 5, 2026
·
1 revision
An OBJECT reference to a TInterfacedObject descendant is set to nil while it holds a fresh instance. Only an interface reference counts; an object reference holds no count, so nil releases nothing and the instance leaks. OFF by default.
function Build: TThing; // TThing = class(TInterfacedObject, IThing)
begin
try
Result := TThing.Create;
Result.Load;
except
Result := nil; // finding: the instance leaks. Return IThing, or Free it.
end;
end;drag-lint lint <file> --rule interfaced-object-nil-leak
drag-lint lint-all --db <project.sqlite> --rule interfaced-object-nil-leak
-
Result := nilwith no instance created before it (the find idiom). - A reference that may have reached an interface holder first: a bare use (
I := T,Sink(T)) or a method call on it (T.Subscribecan hand over Self). In those cases thenilonly clears an alias. - A variable typed as an interface.
-
T.Freebefore thenil. -
if C then X := T.Create else X := nil: the two are on different branches. - A class whose chain to
TInterfacedObjectis unknown. The rule reads the same file, then the index. - A plain class. That is a different leak, and not what this rule is about.