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;
Object : constant Element.I_Interface'Class := Element.T_Class'(null record);
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;
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.
--- 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);