<div>Problem: Free Pascal is not properly initializing and finalizing an interface type resulting in code being invoked for a garbage pointer. The error is highlighted at the end.</div><div><br></div>Previously I filed a bug report on this issue and received feedback that the bug could not be reproduced, but it's hitting me me big time when building on 32-bit Linux (I been working on 64-bit Linux withe same same compiler source without these problems). I'd like to post some code and get feedback on how to fix this problem, if it is either something I am doing or a problem with the compiler.<div>
<br></div><div>I have an interface type, what I would call a managed type since the compiler ought to generate code to initialize and finalize its value, which is used to share 1 or more contiguous floats:</div><div><br></div>
<div><div> IDependencyProperty = interface</div><div> ['{E021AD95-9985-48AB-B29F-8D25A7BBE10E}']</div><div> function GetCount: Integer;</div><div> function GetValue(Index: Integer): Float;</div><div> procedure SetValue(Value: Float; Index: Integer);</div>
<div> property Count: Integer read GetCount;</div><div> end; </div></div><div><br></div><div>The interface is exposed by records TVec(n)Prop where n represents the count or available floats. These properties are used to share float vectors with animations/storyboards or other objects. Here is an the listing of TVec1Prop:</div>
<div><br></div><div><div> TVec1Prop = record</div><div> private</div><div> function GetValue: TVec1;</div><div> procedure SetValue(Value: TVec1);</div><div> function GetVec(Index: Integer): TVec1Prop;</div><div>
procedure SetVec(Index: Integer; const Value: TVec1Prop);</div><div> public</div><div> class operator Implicit(const Value: TVec1): TVec1Prop;</div><div> class operator Implicit(const Value: TVec1Prop): TVec1;</div>
<div> class operator Negative(const A: TVec1Prop): TVec1;</div><div> class operator Positive(const A: TVec1Prop): TVec1;</div><div> class operator Equal(const A, B: TVec1Prop) : Boolean;</div><div> class operator NotEqual(const A, B: TVec1Prop): Boolean;</div>
<div> class operator GreaterThan(const A, B: TVec1Prop): Boolean;</div><div> class operator GreaterThanOrEqual(const A, B: TVec1Prop): Boolean;</div><div> class operator LessThan(const A, B: TVec1Prop): Boolean;</div>
<div> class operator LessThanOrEqual(const A, B: TVec1Prop): Boolean;</div><div> class operator Add(const A, B: TVec1Prop): TVec1;</div><div> class operator Subtract(const A, B: TVec1Prop): TVec1;</div><div> class operator Multiply(const A, B: TVec1Prop): TVec1;</div>
<div> class operator Divide(const A, B: TVec1Prop): TVec1;</div><div> procedure Link(OnChange: TDependencyChangeNotify = nil); overload;</div><div> procedure Link(Prop: IDependencyProperty; Index: LongInt); overload;</div>
<div> procedure Unlink;</div><div> function Linked: Boolean;</div><div> function Equals(const A: TVec1Prop): Boolean;</div><div> function Same(const A: TVec1Prop): Boolean;</div><div> property X: TVec1Prop index 0 read GetVec write SetVec;</div>
<div> property Value: TVec1 read GetValue write SetValue;</div><div> property Vec[Index: Integer]: TVec1Prop read GetVec write SetVec;</div><div> private</div><div> FProp: IDependencyProperty;</div><div> case Boolean of</div>
<div> True: (FIndex: LongInt);</div><div> False: (FValue: TVec1);</div><div> end;</div></div><div><br></div><div>Part of the implementation looks like this with an example of the ERROR in comments:</div><div><br>
</div><div><div>{ TVec1Prop }</div><div><br></div><div>class operator TVec1Prop.Implicit(const Value: TVec1Prop): TVec1;</div><div>begin</div><div> Result := Value.Value;</div><div>end;</div><div><br></div><div>class operator TVec1Prop.Implicit(const Value: TVec1): TVec1Prop;</div>
<div>begin</div><div> // ERROR: WriteLn(UIntPtr(Result.FProp)); writes out a random memory location</div><div> // ERROR: Result.FProp should be nil already but it is not</div><div> Result.FProp := nil; // ERROR: Code is generated which attempts to call release on random garbage</div>
<div> Result.FIndex := 0;</div><div> Result.FValue := Value;</div><div>end;</div><div><br></div><div>function TVec1Prop.GetValue: TVec1;</div><div>begin</div><div> if FProp = nil then</div><div> Result := FValue</div>
<div> else</div><div> Result := FProp.GetValue(FIndex);</div><div>end;</div><div><br></div><div>procedure TVec1Prop.SetValue(Value: TVec1);</div><div>begin</div><div> if FProp = nil then</div><div> FValue := Value</div>
<div> else</div><div> FProp.SetValue(Value, FIndex);</div><div>end;</div></div><div><br></div><div>The problem is happening in a lot of places which use my TVec(n)Prop types, resulting in many AV errors, but again only when I am recompiling my demo programs on 32-bit Linux (with the same compiler source). For example I have a list of TVec1Prop, when I clear the list I am getting AV errors due to some items not being finalized correctly.</div>
<div><br></div><div>What should I do?</div>