[X] This should be a new rule, not an improvement to an existing rule.
[X] This rule would be generally useful, not specific to my code or setup.
Suggested rule title
Class instance variables should not be passed as an interface parameter
Rule description
This rule picks up cases where a variable containing an object instance (e.g. TObject) is passed to a routine that expects an interface (e.g. IInterface). The interface reference causes the object to be reference counted and freed at the end of the routine, meaning that the variable is pointing to freed memory when control is returned to the calling code.
type
IFooIntf = interface
end;
TFooImpl = class(TInterfacedObject, IFooIntf)
end;
procedure DoThing(Foo: IFooIntf);
begin
// ...
end;
procedure Run;
var
FooImpl: TFooImpl;
begin
FooImpl := TFooImpl.Create;
DoThing(FooImpl); // Noncompliant - performs reference counting and destroys object before returning control
FooImpl.Free; // This will cause a double free
end;
Rationale
This is a common "gotcha" as it is a frequent pattern in other languages. It is also a statically verifiable case in which access violations are likely.
Prerequisites
Suggested rule title
Class instance variables should not be passed as an interface parameter
Rule description
This rule picks up cases where a variable containing an object instance (e.g.
TObject
) is passed to a routine that expects an interface (e.g.IInterface
). The interface reference causes the object to be reference counted and freed at the end of the routine, meaning that the variable is pointing to freed memory when control is returned to the calling code.Rationale
This is a common "gotcha" as it is a frequent pattern in other languages. It is also a statically verifiable case in which access violations are likely.