An iterator specification can include a subtype indication in the case of an
array- or container-element iterator. This patch verifies that the subtype
indication matches the element type of the array or container.

Compiling the following must yield:

  range_in_iterator.adb:14:12: subtype indication does not match component type
  range_in_iterator.adb:20:12: subtype indication does not match element type

---
with Ada.Containers.Doubly_Linked_Lists;
procedure Range_In_Iterator is
   Zero : Integer;
   A : String := "hello world";
   type Rec is record
      Val : Integer := 111;
   end record;
   package L is new Ada.Containers.Doubly_Linked_Lists (Rec);
   Chain : L.List;
   
   R : Rec := (Val => 12345);
begin
   Zero := 0;
   for J : Integer  range Zero .. 1 of A loop
      null;
   end loop;

   Chain.Append (R);
   Chain.Append (R);
   for C : Character of Chain loop
      null;
   end loop;
end Range_In_Iterator;

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

2014-01-24  Ed Schonberg  <schonb...@adacore.com>

        * sem_ch5.adb (Analyze_Iterator_Specification): If subtype
        indication is given explicity, check that it matches the array
        component type or the container element type of the domain
        of iteration.

Index: sem_ch5.adb
===================================================================
--- sem_ch5.adb (revision 207026)
+++ sem_ch5.adb (working copy)
@@ -1680,12 +1680,21 @@
 
       Ent : Entity_Id;
       Typ : Entity_Id;
+      Bas : Entity_Id;
 
    begin
       Enter_Name (Def_Id);
 
       if Present (Subt) then
          Analyze (Subt);
+
+         --  Save type of subtype indication for subsequent check.
+
+         if Nkind (Subt) = N_Subtype_Indication then
+            Bas := Entity (Subtype_Mark (Subt));
+         else
+            Bas := Entity (Subt);
+         end if;
       end if;
 
       Preanalyze_Range (Iter_Name);
@@ -1804,6 +1813,13 @@
          if Of_Present (N) then
             Set_Etype (Def_Id, Component_Type (Typ));
 
+            if Present (Subt)
+              and then Bas /= Base_Type (Component_Type (Typ))
+            then
+               Error_Msg_N
+                 ("subtype indication does not match component type", Subt);
+            end if;
+
          --  Here we have a missing Range attribute
 
          else
@@ -1849,6 +1865,17 @@
                else
                   Set_Etype (Def_Id, Entity (Element));
 
+                  --  If subtype indication was given, verify that it matches
+                  --  element type of container.
+
+                  if Present (Subt)
+                     and then Bas /= Base_Type (Etype (Def_Id))
+                  then
+                     Error_Msg_N
+                       ("subtype indication does not match element type",
+                          Subt);
+                  end if;
+
                   --  If the container has a variable indexing aspect, the
                   --  element is a variable and is modifiable in the loop.
 

Reply via email to