8.5.1 Object Renaming Declarations
1
[An object_renaming_declaration
is used to rename an object.]
Syntax
2/2
{
AI95-00230-01}
{
AI95-00423-01}
object_renaming_declaration ::=
defining_identifier :
[null_exclusion] subtype_mark renames object_name;
| defining_identifier : access_definition renames object_name;
Name Resolution Rules
3/2
{
AI95-00230-01}
{
AI95-00254-01}
{
AI95-00409-01}
The type of the
object_name shall resolve
to the type determined by the
subtype_mark,
or in the case where the type is defined by an access_definition,
to an anonymous access type. If the anonymous access type is an access-to-object
type, the type of the object_name shall
have the same designated type as that of the access_definition.
If the anonymous access type is an access-to-subprogram type, the type
of the object_name shall have a designated
profile that is type conformant with that of the access_definition.
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
{
AI95-00231-01}
{
AI95-00409-01}
In the case where the type is defined by an access_definition,
the type of the renamed object and the type defined by the access_definition:
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 {statically matching (required)
[partial]}
4.3/2
- {AI95-00409-01}
shall both be access-to-subprogram types with subtype
conformant designated profiles. {subtype
conformance (required)}
4.4/2
{
AI95-00423-01}
For an object_renaming_declaration
with a null_exclusion or an access_definition
that has a null_exclusion:
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. {generic contract issue [partial]}
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/2
{
8652/0017}
{
AI95-00184-01}
{
AI95-00363-01}
The renamed entity shall not be a subcomponent that depends on discriminants
of a variable whose nominal subtype is unconstrained, unless 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/1
{
8652/0017}
{
AI95-00184-01}
The “recheck on instantiation” and
“assume-the-worst in the body” restrictions on generics 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.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.
5.d/2
To be honest: {
AI95-00363-01}
If renamed entity is a subcomponent that depends
on discriminants, and the subcomponent is a dereference of a general
access type whose designated type is unconstrained and whose discriminants
have defaults, the renaming is illegal. Such a general access type can
designate an unconstrained (stack) object. Since such a type might not
designate an object constrained by its initial value, the renaming is
illegal — the rule says “is” constrained by its initial
value, not “might be” constrained by its initial value. No
other interpretation makes sense, as we can't have legality depending
on something (which object is designated) that is not known at compile-time,
and we surely can't allow this for unconstrained objects. The wording
of the rule should be much clearer on this point, but this was discovered
after the completion of Amendment 1 when it was too late to fix it.
Static Semantics
6/2
{
AI95-00230-01}
{
AI95-00409-01}
An
object_renaming_declaration declares a
new view [of the renamed object] whose properties are identical to those
of the renamed view. [Thus, the properties of the renamed object are
not affected by the
renaming_declaration.
In particular, its value and whether or not it is a constant are unaffected;
similarly, the
null exclusion or constraints
that apply to an object are not affected by renaming (any constraint
implied by the
subtype_mark or
access_definition of the
object_renaming_declaration
is ignored).]
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}
Explicit null_exclusion is not permitted. Null
exclusiveness need not match, in the same 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}
{incompatibilities with Ada 95} 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}
{extensions to Ada 95} 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 a component or stand-alone object).
8.e/2
{
AI95-00231-01}
{
AI95-00423-01}
A renaming can have a null_exclusion;
if so, the renamed object must also exclude null, so that the null_exclusion
does not lie. On the other hand, if the renaming does not have a null_exclusion.
it excludes null of the renamed object does.
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.