Bug#650764: gnat-4.4: FTBFS: sinput.adb:776:19: deallocation from empty storage pool
I have traced this to the following diff hunk in the sources of GNAT:
--- a/gcc/ada/sem_intr.adb 4.4
+++ b/gcc/ada/sem_intr.adb 4.6
@@ -134,12 +159,23 @@ package body Sem_Intr is
-- Check for the case of freeing a non-null object which will raise
-- Constraint_Error. Issue warning here, do the expansion in Exp_Intr.
- elsif Cnam = Name_Free
+ elsif Cnam = Name_Unchecked_Deallocation
and then Can_Never_Be_Null (Etype (Arg1))
then
Error_Msg_N
("freeing `NOT NULL` object will raise Constraint_Error?", N);
+ -- For unchecked deallocation, error to deallocate from empty pool.
+ -- Note: this test used to be in Exp_Intr as a warning, but AI 157
+ -- issues a binding interpretation that this should be an error, and
+ -- consequently it needs to be done in the semantic analysis so that
+ -- the error is issued even in semantics only mode.
+
+ elsif Cnam = Name_Unchecked_Deallocation
+ and then No_Pool_Assigned (Rtyp)
+ then
+ Error_Msg_N ("deallocation from empty storage pool!", N);
+
-- For now, no other special checks are required
else
This explains why gnat-4.6 issues an (unsuppressible) error instead of a
(suppressed) warning when compiling the following piece of source of
gnat-4.4 (line 776 is of course the call to Free_Ptr):
declare
S : Source_File_Record renames Source_File.Table (J);
procedure Free_Ptr is new Unchecked_Deallocation
(Big_Source_Buffer, Source_Buffer_Ptr);
pragma Warnings (Off);
-- This unchecked conversion is aliasing safe, since it is not
-- used to create improperly aliased pointer values.
function To_Source_Buffer_Ptr is new
Unchecked_Conversion (Address, Source_Buffer_Ptr);
pragma Warnings (On);
Tmp1 : Source_Buffer_Ptr;
begin
if S.Instantiation /= No_Location then
null;
else
-- Free the buffer, we use Free here, because we used malloc
-- or realloc directly to allocate the tables. That is
-- because we were playing the big array trick. We need to
-- suppress the warning for freeing from an empty pool!
-- We have to recreate a proper pointer to the actual array
-- from the zero origin pointer stored in the source table.
Tmp1 :=
To_Source_Buffer_Ptr
(S.Source_Text (S.Source_First)'Address);
pragma Warnings (Off);
Free_Ptr (Tmp1);
pragma Warnings (On);
if S.Lines_Table /= null then
Memory.Free (To_Address (S.Lines_Table));
S.Lines_Table := null;
end if;
if S.Logical_Lines_Table /= null then
Memory.Free (To_Address (S.Logical_Lines_Table));
S.Logical_Lines_Table := null;
end if;
end if;
end;
This does not however explain why gnat-4.6 compiles gnat-4.6
successfully, given that sinput.adb has changed very little in that
area:
--- a/gcc/ada/sinput.adb 4.4
+++ b/gcc/ada/sinput.adb 4.6
@@ -763,8 +811,7 @@ package body Sinput is
else
-- Free the buffer, we use Free here, because we used malloc
-- or realloc directly to allocate the tables. That is
- -- because we were playing the big array trick. We need to
- -- suppress the warning for freeing from an empty pool!
+ -- because we were playing the big array trick.
-- We have to recreate a proper pointer to the actual array
-- from the zero origin pointer stored in the source table.
@@ -772,9 +819,7 @@ package body Sinput is
Tmp1 :=
To_Source_Buffer_Ptr
(S.Source_Text (S.Source_First)'Address);
- pragma Warnings (Off);
Free_Ptr (Tmp1);
- pragma Warnings (On);
if S.Lines_Table /= null then
Memory.Free (To_Address (S.Lines_Table));
The mystery disappears when we read the corresponding ChangeLog entry:
2010-10-07 Robert Dewar <dewar@adacore.com>
* par-ch6.adb: Fix error in handling of parametrized expressions.
* par-ch4.adb (P_Name): Allow qualified expression as name in Ada 2012
mode.
(P_Simple_Expression): Better message for qualified expression prefix
* s-crc32.adb: Minor reformatting.
* exp_intr.adb (Expand_Unc_Deallocation): Remove test for empty
storage pool (this test is moved to Sem_Intr).
* sem_intr.adb (Check_Intrinsic_Call): Add check for deallocation from
empty storage pool, moved here from Exp_Intr and made into error.
(Check_Intrinsic_Call): Remove assumption in generating not-null free
warning that the name of the instantiation is Free.
* sinput.adb (Tree_Read): Document use of illegal free call allowed in
GNAT mode.
* types.ads: Remove storage size clauses from big types (since we may
need to do deallocations, which are now illegal for empty pools).
So I think that backporting the entire commit (affecting exp_intr.adb,
sem_intr.adb, sinput.adb and most importantly types.ads) to gnat-4.4
should resolve this bug.
--
Ludovic Brenta.
Reply to: