Expansion of "for X of Y loop" where Y is an array was differed in GNAT
(where it was correct) and GNATprove (where it was wrong).

Typically expansion is controlled by the Expander_Active variable. In
GNATprove mode this variable is always False, so we need to explicitly
enable expansion where required (which is subtle and prone to
errors...).

With this patch, a loop over an array is now expanded for GNATprove just
like for GNAT, in particular, we now get a renaming of the iterated
object:

   R : ... renames Y;
   --  This renaming is crucial to remove side effects from Y, but it
   --  was missing in the GNATprove mode.

   for X in _low_ .. _high_ loop ...

A similar loop over an object that is subject to aspect Iterable is
expanded into a WHILE loop for GNAT, but kept as "FOR ... OF ..." for
GNATprove. With this patch a similar renaming of the iterated object is
created in GNATprove mode:

   R : ... renames Y;
   for X of R loop ...

However, the reference to R must be analyzed, so that a special
expansion of renamed objects for GNATprove replaces it with a reference
to Y.

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

2020-06-17  Piotr Trojanek  <troja...@adacore.com>

gcc/ada/

        * sem_ch5.adb (Analyze_Iterator_Specification): Enable expansion
        that creates a renaming that removes side effects from the
        iterated object in the GNATprove mode; then analyze reference to
        this renaming (it is required for GNATprove and harmless for
        GNAT).
--- gcc/ada/sem_ch5.adb
+++ gcc/ada/sem_ch5.adb
@@ -2214,8 +2214,8 @@ package body Sem_Ch5 is
 
       --  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
-      --  assign to elements.
+      --  The declaration must be a renaming (both in GNAT and GNATprove
+      --  modes), because the body of the loop may assign to elements.
 
       if not Is_Entity_Name (Iter_Name)
 
@@ -2224,14 +2224,15 @@ package body Sem_Ch5 is
         --  doing expansion.
 
         and then (Nkind (Parent (N)) /= N_Quantified_Expression
-                   or else Operating_Mode = Check_Semantics)
+                   or else (Operating_Mode = Check_Semantics
+                            and then not GNATprove_Mode))
 
         --  Do not perform this expansion when expansion is disabled, where the
         --  temporary may hide the transformation of a selected component into
         --  a prefixed function call, and references need to see the original
         --  expression.
 
-        and then Expander_Active
+        and then (Expander_Active or GNATprove_Mode)
       then
          declare
             Id    : constant Entity_Id := Make_Temporary (Loc, 'R', Iter_Name);
@@ -2319,6 +2320,7 @@ package body Sem_Ch5 is
 
             Insert_Actions (Parent (Parent (N)), New_List (Decl));
             Rewrite (Name (N), New_Occurrence_Of (Id, Loc));
+            Analyze (Name (N));
             Set_Etype (Id, Typ);
             Set_Etype (Name (N), Typ);
          end;

Reply via email to