[Ada] Crash on complex conditional involving a packed array indexing

Arnaud Charlet charlet@adacore.com
Thu Jul 31 09:58:00 GMT 2014


This patch updates the freezing of expressions to account for a case when the
freezing expression is part of the Actions list of a N_Expression_With_Actions
node. In this case, any freeze nodes must remain in the Actions list.

------------
-- Source --
------------

--  use_before_decl.adb

with Ada.Text_IO; use Ada.Text_IO;

procedure Use_Before_Decl is
   type String_Ptr is access all String;
   type String_Ptr_Array is array (Positive range <>) of String_Ptr;
   pragma Pack (String_Ptr_Array);
   type String_Ptr_Array_Ptr is access all String_Ptr_Array;

   procedure Print (Data : String_Ptr_Array_Ptr) is
   begin
      if Data = null then
         Put_Line ("Empty");

      else
         for Index in Data.all'Range loop
            if Data.all (Index) /= null
              and then Data.all (Index).all'Length > 0
            then
               Put_Line (Data.all (Index).all);
            end if;
         end loop;
      end if;
   end Print;

   Data : String_Ptr_Array_Ptr;

begin
   Data := new String_Ptr_Array (1 .. 3);
   for Index in Data.all'Range loop
      Data.all (Index) := new String'("Value" & Index'Img);
   end loop;

   Print (Data);
end Use_Before_Decl;

----------------------------
-- Compilation and output --
----------------------------

$ gnatmake -q use_before_decl.adb
$ ./use_before_decl
Value 1
Value 2
Value 3

Tested on x86_64-pc-linux-gnu, committed on trunk

2014-07-31  Hristian Kirtchev  <kirtchev@adacore.com>

	* freeze.adb (Freeze_Expression): Update the loop in charge
	of finding a proper insertion place for freeze nodes to handle
	N_Expression_With_Actions nodes.

-------------- next part --------------
Index: freeze.adb
===================================================================
--- freeze.adb	(revision 213332)
+++ freeze.adb	(revision 213333)
@@ -6143,14 +6143,27 @@
 
                exit when Is_List_Member (P);
 
-            --  Note: The N_Loop_Statement is a special case. A type that
-            --  appears in the source can never be frozen in a loop (this
-            --  occurs only because of a loop expanded by the expander), so we
-            --  keep on going. Otherwise we terminate the search. Same is true
-            --  of any entity which comes from source. (if they have predefined
-            --  type, that type does not appear to come from source, but the
-            --  entity should not be frozen here).
+            --  Freeze nodes produced by an expression coming from the Actions
+            --  list of a N_Expression_With_Actions node must remain within the
+            --  Actions list. Inserting the freeze nodes further up the tree
+            --  may lead to use before declaration issues in the case of array
+            --  types.
 
+            when N_Expression_With_Actions =>
+               if Is_List_Member (P)
+                 and then List_Containing (P) = Actions (Parent_P)
+               then
+                  exit;
+               end if;
+
+            --  Note: N_Loop_Statement is a special case. A type that appears
+            --  in the source can never be frozen in a loop (this occurs only
+            --  because of a loop expanded by the expander), so we keep on
+            --  going. Otherwise we terminate the search. Same is true of any
+            --  entity which comes from source. (if they have predefined type,
+            --  that type does not appear to come from source, but the entity
+            --  should not be frozen here).
+
             when N_Loop_Statement =>
                exit when not Comes_From_Source (Etype (N))
                  and then (No (Nam) or else not Comes_From_Source (Nam));


More information about the Gcc-patches mailing list