An object declaration of a class-wide object with a tag-indeterminate initial value is rewritten as a renaming of a dereference. The renaming must preserve the kind of the object (constant or variable). Previous to this patch, the compiler failed to reject a call to a primitive operation with an in-out controlling formal, when the actual was a constant class-wide object.
Compiling main.adb in -gnat05 mode must yield: main.adb:16:04: actual for "I" must be a variable --- with Element; use Element; procedure Main is Object : constant Element.I_Interface'Class := Element.T_Class'(null record); begin Object.Add; end Main; --- package Element is type I_Interface is interface; procedure Add (I : in out I_Interface) is abstract; function Create return I_Interface'Class; type T_Class is new I_Interface with null record; overriding procedure Add (I : in out T_Class) is null; end Element; Tested on x86_64-pc-linux-gnu, committed on trunk 2012-03-15 Ed Schonberg <schonb...@adacore.com> * exp_ch3.adb (Expand_N_Object_Declaration): When rewriting the declaration of a class-wide object, retain the Ekind to prevent subsequent misuse of constants.
Index: exp_ch3.adb =================================================================== --- exp_ch3.adb (revision 185390) +++ exp_ch3.adb (working copy) @@ -4829,10 +4829,12 @@ -- object renaming declaration ---because these identifiers -- were previously added by Enter_Name to the current scope. -- We must preserve the homonym chain of the source entity - -- as well. + -- as well. We must also preserve the kind of the entity, + -- which may be a constant. Set_Chars (Defining_Identifier (N), Chars (Def_Id)); Set_Homonym (Defining_Identifier (N), Homonym (Def_Id)); + Set_Ekind (Defining_Identifier (N), Ekind (Def_Id)); Exchange_Entities (Defining_Identifier (N), Def_Id); end; end if;