diff mbox

[Ada] In an element iterator, the element is constant if the container is.

Message ID 20151026115533.GA123070@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet Oct. 26, 2015, 11:55 a.m. UTC
This patch adds a legality check to element iterators over containers: the
element is a constant if the container object is a constant, even if the
container type has a Variable_Indexing aspect.

Compiling the following must be rejected with:

 strange_behavior.adb:12:07: left hand side of assignment must be a variable

---
with Ada.Containers.Doubly_Linked_Lists;
procedure Strange_Behavior is
   
   package Integer_Lists is new
      Ada.Containers.Doubly_Linked_Lists (Element_Type => Integer);

   L : constant Integer_Lists.List := Integer_Lists.Empty_List;
      
begin
      
   for Item of L loop
      Item := 0;
   end loop;
      
end Strange_Behavior; 

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

2015-10-26  Ed Schonberg  <schonberg@adacore.com>

	* exp_ch5.adb (Expand_Iterator_Loop_Over_Container): For
	an element iterator loop, the element is a constant if the
	container object is a constant, even if the container type has
	a Variable_Indexing aspect.
diff mbox

Patch

Index: exp_ch5.adb
===================================================================
--- exp_ch5.adb	(revision 229313)
+++ exp_ch5.adb	(working copy)
@@ -3864,10 +3864,14 @@ 
             Set_Debug_Info_Needed (Id);
 
             --  If the container does not have a variable indexing aspect,
-            --  the element is a constant in the loop.
+            --  the element is a constant in the loop. The container itself
+            --  may be constant, in which case the element is a constant as
+            --  well. The container has been rewritten as a call to Iterate,
+            --  so examine original node.
 
             if No (Find_Value_Of_Aspect
                      (Container_Typ, Aspect_Variable_Indexing))
+              or else not Is_Variable (Original_Node (Container))
             then
                Set_Ekind (Id, E_Constant);
             end if;