I have the following program:
procedure Main with SPARK_Mode is
F : array (0 .. 10) of Integer := (0, 1, others => 0);
begin
for I in 2 .. F'Last loop
F (I) := F (I - 1) + F (I - 2);
end loop;
end Main;
If I run gnatprove
, I get the following result, pointing to the +
sign:
medium: overflow check might fail
Does this mean that F (I - 1)
could be equal to Integer'Last
, and adding anything to that would overflow? If so, then is it not clear from the flow of the program that this is impossible? Or do I need to specify this with a contract? If not, then what does it mean?
A counterexample shows that indeed gnatprove
in this case worries about the edges of Integer
:
medium: overflow check might fail (e.g. when
F = (1 => -1, others => -2147483648)
andI = 2
)
F (I) <= 2 * I
for allI
? – PredecessorI <= 7
, and would be false otherwise. – Alibignatprove
unroll the loop before passing it to the provers. – PredecessorF
would come from user input instead of being the constant10
? – Alibi