If nested loops appear where the iteration ranges are over the
same range of a multi-dimensional range (where the range number
has been defaulted to 1), then a warning is issued as shown in
the following example:
1. procedure Warn2D is
2. type E is array (Integer range <>, Integer range <>)
3. of Integer;
4. S : Integer := 0;
5. EE : E (1 .. 3, 1 .. 3) := (Others => (Others => 0));
6. begin
7. for J in EE'Range loop
8. for K in EE'Range loop
|
>>> warning: inner range same as outer range at line 7
9. S := S + EE (J, K);
10. end loop;
11. end loop;
12. end Warn2D;
Tested on x86_64-pc-linux-gnu, committed on trunk
2012-10-29 Robert Dewar <[email protected]>
* sem_ch5.adb (Analyze_Loop_Statement): Add warning for identical
inner/outer ranges.
Index: sem_ch5.adb
===================================================================
--- sem_ch5.adb (revision 192908)
+++ sem_ch5.adb (working copy)
@@ -2626,6 +2626,56 @@
Push_Scope (Ent);
Analyze_Iteration_Scheme (Iter);
+ -- Check for following case which merits a warning if the type E of is
+ -- a multi-dimensional array (and no explicit subscript ranges present).
+
+ -- for J in E'Range
+ -- for K in E'Range
+
+ if Present (Iter)
+ and then Present (Loop_Parameter_Specification (Iter))
+ then
+ declare
+ LPS : constant Node_Id := Loop_Parameter_Specification (Iter);
+ DSD : constant Node_Id :=
+ Original_Node (Discrete_Subtype_Definition (LPS));
+ begin
+ if Nkind (DSD) = N_Attribute_Reference
+ and then Attribute_Name (DSD) = Name_Range
+ and then No (Expressions (DSD))
+ then
+ declare
+ Typ : constant Entity_Id := Etype (Prefix (DSD));
+ begin
+ if Is_Array_Type (Typ)
+ and then Number_Dimensions (Typ) > 1
+ and then Nkind (Parent (N)) = N_Loop_Statement
+ and then Present (Iteration_Scheme (Parent (N)))
+ then
+ declare
+ OIter : constant Node_Id :=
+ Iteration_Scheme (Parent (N));
+ OLPS : constant Node_Id :=
+ Loop_Parameter_Specification (OIter);
+ ODSD : constant Node_Id :=
+ Original_Node (Discrete_Subtype_Definition (OLPS));
+ begin
+ if Nkind (ODSD) = N_Attribute_Reference
+ and then Attribute_Name (ODSD) = Name_Range
+ and then No (Expressions (ODSD))
+ and then Etype (Prefix (ODSD)) = Typ
+ then
+ Error_Msg_Sloc := Sloc (ODSD);
+ Error_Msg_N
+ ("inner range same as outer range#?", DSD);
+ end if;
+ end;
+ end if;
+ end;
+ end if;
+ end;
+ end if;
+
-- Analyze the statements of the body except in the case of an Ada 2012
-- iterator with the expander active. In this case the expander will do
-- a rewrite of the loop into a while loop. We will then analyze the