[fpc-devel] Data flow analysis (dfa) and "case ... of"

Denis Kozlov dezlov at gmail.com
Thu Jun 8 02:22:08 CEST 2017


On 07/06/2017 15:18, Juha Manninen wrote:
> The compiler trusts that data in an enum variable is legal, within the range.
> It should trust the same way when doing DFA. It is logical and consistent.

I understand your reasons now and agree that DFA should cover only 
logical (according to the compiler) scenarios.

Juha Manninen wrote:
> What you must do is add sanity checks for code that initializes enum
> data based on some other data.
> .....
> The same way if you get integer data from I/O, you must verify the
> integer is within range _before_ typecasting it.

Sanity checks is exactly what I do, but in both directions (see example 
below).

I can't control what values other users/developers may supply, nor I 
restrict the use of different compiler versions and build flags. It is 
because "TConvertType(-1)" and the likes are an acceptable statement for 
compiler, I make it my responsibility to handle all possible input 
values, no matter how illogical and invalid they may be. This is a 
design pattern that I follow.

If the 'else' condition is optimized away in certain compiler versions 
and/or by certain complier optimization flags, that is no problem, at 
least not for me. Then, as Martin highlighted, "unreachable code" 
warning may be appropriate.

Currently, TConvertType(X) doesn't produce any errors where X is out of 
declared range of TConvertType. So I shall continue to account for 
potential invalid values, even if my attempts may be optimized away in 
some circumstances. I might be trying to account for an illegal or 
undefined behaviour, but I do nonetheless, if it improves the chances of 
catching errors earlier.

type
   TConvertType = (ctA, ctB);

function StrToConvert(const Value: String): TConvertType;
begin
   case Value of
     'A': Result := ctA;
     'B': Result := ctB;
     else raise Exception.CreateFmt('Invalid convert value string (%s)', 
[Value]);
   end;
end;

function Convert(Value: TConvertType): Integer;
begin
   case Value of
     ctA: Result := 1;
     ctB: Result := 2;
     else raise Exception.CreateFmt('Invalid convert value (%d)', 
[Ord(Value)]);
   end;
end;



More information about the fpc-devel mailing list