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 <de...@adacore.com> * 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