diff mbox series

[Ada] Crash on illegal use of iterated component association

Message ID 20170929132517.GA145350@adacore.com
State New
Headers show
Series [Ada] Crash on illegal use of iterated component association | expand

Commit Message

Pierre-Marie de Rodat Sept. 29, 2017, 1:25 p.m. UTC
An iterated component association is an Ada2020 extension that simplifies
the construction of array aggregates.  This patch properly rejects the use
of this construct as a named association in an aggregate for a record type.

compiling
   gcc -c -gnat2020 klurigt-m2.adb

must yield:

   klurigt-m2.adb:11:12:
     iterated component association can only appear in an array aggregate
   compilation abandoned

---
with Klurigt.Conv;use Klurigt.Conv;
procedure Klurigt.M2 is

   function Bar_Of
     (Bar : in Bar_Type)
      return My_Bar_Type
   is
   begin
      return Result : constant My_Bar_Type
        := (for Index in 1 .. Foo_Index_Type (Bar.Foos'Last) =>
                Foo_Of (Bar.Foos (Foo_Index_Type (Index))))
      do
         null;
      end return; 
   end Bar_Of;
begin
   null;
end Klurigt.M2;
---
package Klurigt is
   type Foo_Type
   is record
      Kalle : Natural := 0;
      Olle  : Integer := 0;
   end record;

   type Foo_Index_Type is new Natural;

   MAX_FOO_ARRAY_SIZE : constant Foo_Index_Type := 10;

   type Foo_Array_Type is array (1 .. MAX_FOO_ARRAY_SIZE) of Foo_Type;

   type Bar_Type
   is record
      Foos : Foo_Array_Type;
   end record;

   type My_Natural_Type is new Natural;
   type My_Integer_Type is new Integer;

   type My_Foo_Type
   is record
      Kalle : My_Natural_Type := 0;
      Olle  : My_Integer_Type := 0;
   end record;

   type My_Foo_Array_Index_Type is new Integer;

   MAX_MY_FOO_ARRAY_SIZE : constant My_Foo_Array_Index_Type := 10;

   type My_Foo_Array_Type is array (1 .. MAX_MY_FOO_ARRAY_SIZE) of My_Foo_Type;

   type My_Bar_Type
   is record
      Foos : My_Foo_Array_Type;
   end record;
end Klurigt;
---
package Klurigt.Conv is
   function Foo_Of
     (Foo : in Foo_Type)
      return My_Foo_Type
   is (Kalle => My_Natural_Type (Foo.Kalle),
       Olle  => My_Integer_Type (Foo.Olle));
end Klurigt.Conv;

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

2017-09-29  Ed Schonberg  <schonberg@adacore.com>

	* sem_aggr.adb (Resolve_Record_Aggregate): Reject the use of an
	iterated component association in an aggregate for a record type.
diff mbox series

Patch

Index: sem_aggr.adb
===================================================================
--- sem_aggr.adb	(revision 253283)
+++ sem_aggr.adb	(working copy)
@@ -4108,15 +4108,22 @@ 
          begin
             Assoc := First (Component_Associations (N));
             while Present (Assoc) loop
-               if List_Length (Choices (Assoc)) > 1 then
-                  Check_SPARK_05_Restriction
-                    ("component association in record aggregate must "
-                     & "contain a single choice", Assoc);
-               end if;
+               if Nkind (Assoc) = N_Iterated_Component_Association then
+                  Error_Msg_N ("iterated component association can only "
+                    & "appear in an array aggregate", N);
+                  raise Unrecoverable_Error;
 
-               if Nkind (First (Choices (Assoc))) = N_Others_Choice then
-                  Check_SPARK_05_Restriction
-                    ("record aggregate cannot contain OTHERS", Assoc);
+               else
+                  if List_Length (Choices (Assoc)) > 1 then
+                     Check_SPARK_05_Restriction
+                       ("component association in record aggregate must "
+                        & "contain a single choice", Assoc);
+                  end if;
+
+                  if Nkind (First (Choices (Assoc))) = N_Others_Choice then
+                     Check_SPARK_05_Restriction
+                       ("record aggregate cannot contain OTHERS", Assoc);
+                  end if;
                end if;
 
                Assoc := Next (Assoc);