<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>