[fpc-devel] Wrong docs: not initialized global variables

Ondrej Pokorny lazarus at kluug.net
Wed Jul 4 00:26:00 CEST 2018


On 03.07.2018 23:09, Florian Klämpfl wrote:
> Am 03.07.2018 um 22:57 schrieb Ondrej Pokorny:
>> On 03.07.2018 22:08, Florian Klämpfl wrote:
>>> Am 03.07.2018 um 21:30 schrieb Ondrej Pokorny:
>>>> On 03.07.2018 20:54, Florian Klämpfl wrote:
>>>> program Project1;
>>>> type
>>>>    TMyArray = array[0..10] of Integer;
>>>>    procedure Init2(var A: TMyArray);
>>>>    begin
>>>>      A[2] := 1;
>>>>    end;
>>>> var
>>>>    A: TMyArray;
>>>> begin
>>>>    Init2(A);
>>>> end.
>>>>
>>>> should not emit the warning because A is not being read in Init2.
>>>
>>> (please note it throws only a hint in this case as A *is* 
>>> initialized as it is a global variable).
>>>
>>> FPC has no global data flow analysis (and I do not plan to do so 
>>> yet), so this is warning is currently far out of reach.
>>
>> Doing it for SetLength/FillChar would be a good start.
>
> For me: Too much effort for very little gain. Global data flow 
> analysis in general is really a difficult topic and its advantages are 
> oversee-able imo.

Although being a little bit off-topic, IMO it's not that hard and the 
tools are in FPC already now. You have analysis for uninitialized local 
variable already. Use the same approach for the var argument and store 
the result as an argument flag:

procedure ProcA(var A: Integer);
var
   AA: Integer;
begin
   AA := AA + 1; // warning here
   A := A + 1; // same situation as with AA: warning for AA -> set the 
"var A" flag to "data in" + "data out"
end;

procedure ProcB(var B: Integer);
var
   BB: Integer;
begin
   BB := 1; // no warning here
   B := 1; // same situation as with BB: no warning for BB -> set the 
"var B" flag to "data not in" + "data out"
end;

procedure Test;
var
   X, Y: Integer;
begin
   ProcA(X); // << warning here because ProcA.A flag is "data in"
   ProcB(Y); // << no warning here because ProcB.B flag is "data not in"
end;

Then you should handle the "data not out"/"data out" flag as well. Yes, 
probably this analysis is an overkill and it only slows down the 
compiler with little advantage.

Such an analysis is not needed for SetLength because the flag "data not 
in"+"data not out" is there per definition. I agree about FillChar - I 
forgot it is a normal routine and not an intrinsic, so no luck with an 
assumption here.


> The compiler is ~400k lines and I had to fix maybe 40 locations, so I 
> wouldn't call this significantly and there are situations where it 
> matters, see the result case.

If you refer to:

function DoSomething (len: Integer): Vector;
begin
   SetLength(Result, len);
end;

IMO SetLength should be either invisible for variable initialization 
warning detection (because "data not in"+"data not out") or it should be 
a trigger for an uninitialized warning in subsequent code. (Probably the 
former case is easier and better.)

In both cases I described in the last paragraph, you should not emit a 
warning at SetLength call but you should emit a warning as if the 
routine was empty:
function DoSomething (len: Integer): Vector;
begin
end;
 >>> project1.lpr(6,10) Warning: Function result does not seem to be set

But yes, I agree that emitting a warning at SetLength is even easier. So 
yes, you are right. Better to show a warning at SetLength than not 
showing it at all.

Ondrej



More information about the fpc-devel mailing list