Patchwork [Ada] Spurious warnings on iterators over subcomponents

login
register
mail settings
Submitter Arnaud Charlet
Date Sept. 2, 2011, 6:52 a.m.
Message ID <20110902065204.GA18957@adacore.com>
Download mbox | patch
Permalink /patch/113040/
State New
Headers show

Comments

Arnaud Charlet - Sept. 2, 2011, 6:52 a.m.
Iterator of the form "of" generate renamings for the container elements. If
the container that is the domain of iteration is a subcomponent of a larger
object, and an assignment is performed on the element, the larger object must
be marked as modified as well.

The following must compile quietly:

   gcc -c -gnatwa -gnat12 loop_for_of_false_warning.adb

---
procedure Loop_For_Of_False_Warning is
   type Discri_Type is (Case_A, Case_B);
   type Discri2_Type is (Case2_A, Case2_B);

   type R_Type (D : Discri_Type := Case_A) is record
      N : Integer;

      case D is
         when Case_A =>
            I : Integer;

         when Case_B =>
            F : Float;
      end case;
   end record;

   type T_Type is array (Positive range 1 .. 10) of R_Type;

   type R2_Type (D : Discri2_Type := Case2_A) is record
      case D is
         when Case2_A =>
            T_A : T_Type;

         when Case2_B =>
            T_B : T_Type;
      end case;
   end record;

   procedure Process (V : in out R2_Type)
   is
   begin
      if V.D = Case2_B then
         for Element of V.T_B
         loop
            Element.N := 10;
         end loop;
   end Process;

   X : R2_Type;
begin
   Process (X);
end Loop_For_Of_False_Warning;

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

2011-09-02  Ed Schonberg  <schonberg@adacore.com>

	* sem_util.adb (Note_Possible_Modification): If the entity
	being modified is the renaming generated for an Ada2012 iterator
	element, the enclosing container or array is modified as well.

Patch

Index: sem_util.adb
===================================================================
--- sem_util.adb	(revision 178381)
+++ sem_util.adb	(working copy)
@@ -10711,6 +10711,18 @@ 
                then
                   Exp := Renamed_Object (Ent);
                   goto Continue;
+
+               --  The expression may be the renaming of a subcomponent of an
+               --  array or container. The assignment to the subcomponent is
+               --  a modification of the container.
+
+               elsif Comes_From_Source (Original_Node (Exp))
+                 and then
+                   Nkind_In (Original_Node (Exp),
+                     N_Selected_Component, N_Indexed_Component)
+               then
+                  Exp := Prefix (Original_Node (Exp));
+                  goto Continue;
                end if;
 
                --  Generate a reference only if the assignment comes from