This patch improves on the error message for a loop iterator where the loop
variable is referenced in the name of the iterator.

Compiling main.adb must yield:

    main.adb:26:17: object "X" cannot be used before end of its declaration

---
pragma Ada_2012;
pragma Warnings (Off);

with Ada.Text_IO;           use Ada.Text_IO;
with Ada.Containers.Vectors;

procedure Main is

   package Integer_Vectors is new Ada.Containers.Vectors
     (Positive, Integer);

   use Integer_Vectors;

   function F1 (I : Integer) return Vector;

   function F1 (I : Integer) return Vector
   is
      V : Vector;
   begin
      return V;
   end F1;

   X : Integer;
begin

   for X of F1 (X) loop
      null;
   end loop;

end Main;

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

2012-05-15  Ed Schonberg  <schonb...@adacore.com>

        * sem_ch5.adb (Analyze_Iterator_Specification): Set kind of
        loop variable after pre-analysis of iterator name, to prevent
        premature usage of loop variable.

Index: sem_ch5.adb
===================================================================
--- sem_ch5.adb (revision 187522)
+++ sem_ch5.adb (working copy)
@@ -1650,7 +1650,6 @@
 
    begin
       Enter_Name (Def_Id);
-      Set_Ekind (Def_Id, E_Variable);
 
       if Present (Subt) then
          Analyze (Subt);
@@ -1658,6 +1657,11 @@
 
       Preanalyze_Range (Iter_Name);
 
+      --  Set the kind of the loop variable, which is not visible within
+      --  the iterator name.
+
+      Set_Ekind (Def_Id, E_Variable);
+
       --  If the domain of iteration is an expression, create a declaration for
       --  it, so that finalization actions are introduced outside of the loop.
       --  The declaration must be a renaming because the body of the loop may
@@ -1679,6 +1683,13 @@
          begin
             Typ := Etype (Iter_Name);
 
+            --  Protect against malformed iterator.
+
+            if Typ = Any_Type then
+               Error_Msg_N ("invalid expression in loop iterator", Iter_Name);
+               return;
+            end if;
+
             --  The name in the renaming declaration may be a function call.
             --  Indicate that it does not come from source, to suppress
             --  spurious warnings on renamings of parameterless functions,

Reply via email to