[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