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 <kirtc...@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.
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));