8.5.1 Object Renaming Declarations
1
Syntax
2/3
Name Resolution Rules
3/2
3.a
Reason: A
previous version of Ada 9X used the usual “expected type”
wording:
“The expected type for the
object_name
is that determined by the
subtype_mark.”
We changed it so that this would be illegal:
3.b
X: T;
Y: T'Class renames X; -- Illegal!
3.c
When the above
was legal, it was unclear whether Y was of type T or T'Class. Note that
we still allow this:
3.d
Z: T'Class := ...;
W: T renames F(Z);
3.e
where F is a function with a controlling parameter
and result. This is admittedly a bit odd.
3.f
Note that the matching rule for generic formal
parameters of mode in out was changed to keep it consistent with
the rule for renaming. That makes the rule different for in vs.
in out.
Legality Rules
4
The renamed entity shall be an object.
4.1/2
4.2/2
{
AI95-00231-01}
{
AI95-00409-01}
shall both be access-to-object types with statically
matching designated subtypes and with both or neither being access-to-constant
types; or
4.3/2
{
AI95-00409-01}
shall both be access-to-subprogram types with subtype
conformant designated profiles.
4.4/2
4.5/2
if the object_name
denotes a generic formal object of a generic unit G, and the object_renaming_declaration
occurs within the body of G or within the body of a generic unit
declared within the declarative region of G, then the declaration
of the formal object of G shall have a null_exclusion;
4.6/2
otherwise, the subtype of
the object_name
shall exclude null. In addition to the places where
Legality Rules normally apply (see 12.3),
this rule applies also in the private part of an instance of a generic
unit.
4.a/2
Reason:
This rule prevents “lying”. Null must never be
the value of an object with an explicit null_exclusion.
The first bullet is an assume-the-worst rule which prevents trouble in
one obscure case:
4.b/2
type Acc_I is access Integer;
subtype Acc_NN_I is not null Acc_I;
Obj : Acc_I := null;
4.c/2
generic
B : in out Acc_NN_I;
package Gen is
...
end Gen;
4.d/2
package body Gen is
D : not null Acc_I renames B;
end Gen;
4.e/2
package Inst is new Gen (B => Obj);
4.f/2
Without the first bullet
rule, D would be legal, and contain the value null, because the
rule about lying is satisfied for generic matching (Obj matches B; B
does not explicitly state not null), Legality Rules are not rechecked
in the body of any instance, and the template passes the lying rule as
well. The rule is so complex because it has to apply to formals used
in bodies of child generics as well as in the bodies of generics.
5/3
{
8652/0017}
{
AI95-00184-01}
{
AI95-00363-01}
{
AI05-0008-1}
The renamed entity shall not be a subcomponent that depends on discriminants
of
an object a variable
whose nominal subtype is unconstrained
,
unless
the object is known to be constrained this
subtype is indefinite, or the variable is constrained
by its initial value aliased.
A
slice
of an array shall not be renamed if this restriction disallows renaming
of the array.
In addition to
the places where Legality Rules normally apply, these rules apply also
in the private part of an instance of a generic unit. These rules also apply for a renaming that appears in the body of a generic
unit, with the additional requirement that even if the nominal subtype
of the variable is indefinite, its type shall not be a descendant of
an untagged generic formal derived type.
5.a
Reason: This prevents renaming of subcomponents
that might disappear, which might leave dangling references. Similar
restrictions exist for the Access attribute.
5.a.1/3
{
8652/0017}
{
AI95-00184-01}
{
AI05-0008-1}
The “recheck on instantiation” requirement and
“assume-the-worst in the body” restrictions on generics is are necessary to avoid renaming of components which could disappear even
when the nominal subtype would prevent the problem:
5.a.2/1
type T1 (D1 : Boolean) is
record
case D1 is
when False =>
C1 : Integer;
when True =>
null;
end case;
end record;
5.a.3/1
generic
type F is new T1;
X : in out F;
package G is
C1_Ren : Integer renames X.C1;
end G;
5.a.4/1
type T2 (D2 : Boolean := False) is new T1 (D1 => D2);
Y : T2;
package I is new G (T2, Y);
Y := (D1 => True); -- Oops! What happened to I.C1_Ren?
5.a.5/3
{
AI05-0008-1}
In addition, the “known to be constrained”
rules include assume-the-worst rules for generic bodies partially to
prevent such problems.
5.b
Implementation Note: Note that if an
implementation chooses to deallocate-then-reallocate on
assignment_statements
assigning to unconstrained definite objects, then it cannot represent
renamings and access values as simple addresses, because the above rule
does not apply to all components of such an object.
5.c
Ramification: If it is a generic formal
object, then the assume-the-best or assume-the-worst rules are applied
as appropriate.
Static Semantics
6/2
6.a
Discussion: Because the constraints are
ignored, it is a good idea to use the nominal subtype of the renamed
object when writing an
object_renaming_declaration.
6.b/2
{
AI95-00409-01}
If no null_exclusion
is given in the renaming, the object may or may not exclude null. This
is similar to the way that constraints need not match, and constant
is not specified. The renaming defines a view of the renamed entity,
inheriting the original properties.
Examples
7
Example of renaming
an object:
8
declare
L : Person
renames Leftmost_Person; --
see 3.10.1
begin
L.Age := L.Age + 1;
end;
Wording Changes from Ada 83
8.a
The phrase “subtype ... as defined in
a corresponding object declaration, component declaration, or component
subtype indication,” from RM83-8.5(5), is incorrect in Ada 95;
therefore we removed it. It is incorrect in the case of an object with
an indefinite unconstrained nominal subtype.
Incompatibilities With Ada 95
8.b/2
{
AI95-00363-01}
Aliased variables are not necessarily
constrained in Ada 2005 (see 3.6). Therefore,
a subcomponent of an aliased variable may disappear or change shape,
and renaming such a subcomponent thus is illegal, while the same operation
would have been legal in Ada 95. Note that most allocated objects are
still constrained by their initial value (see 4.8),
and thus have no change in the legality of renaming for them. For example,
using the type T2 of the previous example:
8.c/2
AT2 : aliased T2;
C1_Ren : Integer renames AT2.C1; -- Illegal in Ada 2005, legal in Ada 95
AT2 := (D1 => True); -- Raised Constraint_Error in Ada 95,
-- but does not in Ada 2005, so C1_Ren becomes
-- invalid when this is assigned.
Extensions to Ada 95
8.d/2
{
AI95-00230-01}
{
AI95-00231-01}
{
AI95-00254-01}
{
AI95-00409-01}
A renaming can have an anonymous
access type. In that case, the accessibility of the renaming is that
of the original object (accessibility is not lost as it is for assignment
to a component or stand-alone object).
8.e/2
Wording Changes from Ada 95
8.f/2
{
8652/0017}
{
AI95-00184-01}
Corrigendum: Fixed to forbid renamings of
depends-on-discriminant components if the type might be definite.
Incompatibilities With Ada 2005
8.g/3
{
AI05-0008-1}
Correction: Simplified
the description of when a discriminant-dependent component is allowed
to be renamed — it's now simply when the object is known to be
constrained. This fixes a confusion as to whether a subcomponent of an
object that is not certain to be constrained can be renamed. The fix
introduces an incompatibility, as the rule did not apply in Ada 95 if
the prefix was a constant; but it now applies no matter what kind of
object is involved. The incompatibility is not too bad, since most kinds
of constants are known to be constrained.
Extensions to Ada 2005
8.h/3
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe