diff mbox

[Ada] Box associations for components without defaults in aggregates

Message ID 20111013103515.GA2858@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet Oct. 13, 2011, 10:35 a.m. UTC
Box associations are used to initialize aggregate components through the default
value of the corresponding components, or through calls to initialization
procedures. In general aggregates with such initializations cannot be built
statically. With this patch the following must compile quietly:

   gcc -c -gnat05 p.adb

---
procedure P is
   type A1 is array (1 .. 2, 1 .. 2) of Integer;
   A : A1;
begin
   A := ((1 => 2, others => <>), (others => 0));
end P;

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

2011-10-13  Ed Schonberg  <schonberg@adacore.com>

	* exp_aggr.adb (Flatten): If a component association has a box,
	assume that aggregate is not static.
	(Safe_Aggregate): If a component association in a non-limited
	aggregate has a box, assume that it cannot be expanded in place.
diff mbox

Patch

Index: exp_aggr.adb
===================================================================
--- exp_aggr.adb	(revision 179894)
+++ exp_aggr.adb	(working copy)
@@ -3398,6 +3398,15 @@ 
             begin
                Assoc := First (Component_Associations (N));
                while Present (Assoc) loop
+
+                  --  If this is a box association, flattening is in general
+                  --  not possible because at this point we cannot tell if the
+                  --  default is static or even exists.
+
+                  if Box_Present (Assoc) then
+                     return False;
+                  end if;
+
                   Choice := First (Choices (Assoc));
 
                   while Present (Choice) loop
@@ -4148,6 +4157,12 @@ 
                         return False;
                      end if;
 
+                  --  If association has a box, no way to determine yet
+                  --  whether default can be assigned in place.
+
+                  elsif Box_Present (Expr) then
+                     return False;
+
                   elsif not Safe_Component (Expression (Expr)) then
                      return False;
                   end if;