If the left-hand side of an assignment is an Ada 2012 generalized indexing with an implicit derenference, the compiler must verify that the type of the access discriminant that provides the implicit dereference is not an access_to_constant.
Compiling ada_test.adb must yield: ada_test.adb:24:25: left hand side of assignment must be a variable ada_test.adb:25:04: left hand side of assignment must be a variable --- with Ada.Text_IO; use Ada.Text_IO; with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; procedure Ada_Test is type Obj is record A : aliased Integer; end record; type Obj_Access is access all Obj; type Accessor (Data : access constant Integer) is null record with Implicit_Dereference => Data; function Get_Int (This : Obj_Access) return Accessor is begin return Accessor'(Data => This.A'Access); end Get_Int; X : aliased Obj := (A => 11); X_Ptr : Obj_Access := X'Access; begin Get_Int (X_Ptr).Data.all := 33; -- Error Get_Int (X_Ptr) := 33; -- Error Put (X.A); -- Should never execute.. New_Line; end Ada_Test; Tested on x86_64-pc-linux-gnu, committed on trunk 2014-11-20 Ed Schonberg <schonb...@adacore.com> * sem_util.adb (Is_Variable): For an Ada 2012 implicit dereference introduced for an indexing opertion, check that the type of the corresponding access discriminant is not an access to constant.
Index: sem_util.adb =================================================================== --- sem_util.adb (revision 217829) +++ sem_util.adb (working copy) @@ -12806,12 +12806,14 @@ Is_Variable_Prefix (Original_Node (Prefix (N))); -- in Ada 2012, the dereference may have been added for a type with - -- a declared implicit dereference aspect. + -- a declared implicit dereference aspect. Check that it is not an + -- access to constant. elsif Nkind (N) = N_Explicit_Dereference and then Present (Etype (Orig_Node)) and then Ada_Version >= Ada_2012 and then Has_Implicit_Dereference (Etype (Orig_Node)) + and then not Is_Access_Constant (Etype (Prefix (N))) then return True;