Hi, my book is older than the introduction of access types in spark so maybe that’s why I missed something. So we have a case of a package whose public part is in Spark but not the private part nor the body. The driver is also spark. Goes like this:
private with Ada.Finalization;
package Interval_Trees with SPARK_Mode => On
is
type Interval is record
Low : Float;
High : Float;
end record with Predicate => Low < High;
type Tree is limited private;
procedure Insert (T : in out Tree; Item : in Interval) with Depends => (T => (T, Item));
function Check_Overlap (T : Tree; Item : Interval) return Boolean;
private
pragma SPARK_Mode (Off);
type Tree_Node;
type Tree_Node_Access is access Tree_Node;
type Tree_Node is record
-- irrelevant
end record;
type Tree is new Ada.Finalization.Limited_Controlled with record
Root : Tree_Node_Access := null;
Count : Natural := 0;
end record;
overriding procedure Finalize (T : in out Tree);
end Interval_Trees;
While the driver goes like this:
with Interval_Trees, gnat.IO; use Interval_Trees, gnat.IO;
procedure interval_test with spark_mode is
T: Tree;
begin
Insert (T, (19.33, 29.0));
put_line (Check_overlap(T, (1.00, 24.2))'Image);
end interval_test;
Gnatprove complains that T is not initialized when Insert is called, and that memory might not be initialized when Check_overlap tries to read it. But T is default-initialized, and both subprograms takes the null value into account.
Maybe it comes from the full type and default value being out of reach for the prover ?