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 <[email protected]>
* 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,