Version 1.1 of ai12s/ai12-0407-1.txt
!standard 13.1.1(17/5) 20-11-23 AI12-0407-1/01
!standard A.5.6(3/5)
!standard A.5.6(15/5)
!standard A.5.7(3/5)
!standard A.5.7(16/5)
!standard H.4.1(1/5)
!standard H.4.1(3/5)
!standard H.4.1(4/5)
!standard H.4.1(5/5)
!class Amendment 20-11-23
!status Amendment 1-2012 20-11-23
!status work item 20-11-23
!status received 20-11-23
!priority Low
!difficulty Easy
!subject Fixups from Draft 26 review - part 1
!summary
(1) We use the new named number mechanism in the Big_Number packages,
and make some naming improvements.
(2) Language-defined aspects cannot be specified on renamings or generic
formal parameters unless they explicitly allow those uses.
(3) Aspect No_Controlled_Parts is a representation aspect that looks through
privacy.
!problem
(1) AI12-0394-1 added a mechanism to use named numbers with user-defined
literals. But we did not add that mechanism to the Big_Reals package. That
isn't responsive to the original question.
(2) The Nonblocking/Global changes included removing 13.1.1(17/5), with the
body portion of the rule being moved to 13.1.1(18/5). But this removes the
renaming and generic formal parameter parts of the rule. While we now have
some aspects that we allow on generic formal parameters, the majority of
aspects are not view-specific. For such aspects, we need matching or
replacement rules in order to support them on renaming and generic formal
parameters. No such rules exist for most aspects; their definitions assumed
that 13.1.1(17/5) eliminated the need. We need some sort of replacement.
(3) Legality Rules in Ada generally do not look through private types at
the full definition. For aspect No_Controlled_Parts, this would allow hiding
controlled components in a private type. That would defeat the purpose of the
aspect.
!proposal
(1) Add renamings of From_String to From_Universal_Image to both the
Big_Integer and Big_Real packages. Use From_Universal_Image as the
Integer_Literal/Real_Literal aspect. Add an expression function to Big_Real
to provide the two parameter version of From_Universal_Image.
(2) Replace a version of 13.1.1(17/5), with the words "unless otherwise
specified for a specific aspect" preceding it.
(3) Clarify that No_Controlled_Parts looks through privacy when enforcing its
restrictions. Improve the generic assume-the-worst rules.
!wording
[Editor's note: These changes were applied to Draft 27 of the Ada 202x RM,
even though they have not yet been approved, in order that that draft be as
accurate as possible.]
Replace deleted 13.1.1(17/5) with:
Unless otherwise specified for a specific aspect, a language-defined aspect
cannot be specified on a renaming_declaration or a
generic_formal_parameter_declaration.
Modify A.5.6(3/5):
type Big_Integer is private
with Integer_Literal => From_[String]{Universal_Image},
Put_Image => Put_Image;
Add after A.5.6(15/5):
function From_Universal_Image (Arg : String) return Valid_Big_Integer
renames From_String;
Modify A.5.7(3/5):
type Big_Real is private
with Integer_Literal => From_[String]{Universal_Image},
Put_Image => Put_Image;
Add after A.5.7(16/5):
function From_Universal_Image (Arg : String) return Valid_Big_Real
renames From_String;
function From_Universal_Image (Num, Den : String) return Valid_Big_Real is
(Big_Integers.From_Universal_Image (Num) /
Big_Integers.From_Universal_Image (Den));
Modify H.4.1(4/5):
If No_Controlled_Parts is True for a type, no component of the type shall have
a controlled part nor shall the type itself be controlled. {For the purposes
of this rule, a type has a controlled part if its full type has a controlled
part; this is applied recursively.} In addition to the places where Legality
Rules normally apply (see 12.3), this rule also applies in the private part of
an instance of a generic unit.
Add an AARM note:
AARM Discussion: This check breaks privacy by looking at the
full definition of all of the types involved. This is more like a
representation aspect than an operational aspect, but representation
aspects are not allowed on partial views and we need this aspect
to be visible.
Modify H.4.1(5/5):
When enforcing the above rule within a generic body {G or within the body of
a generic unit declared within the declarative region of generic unit G}, a
generic formal private type {of G} and a generic formal derived type {of G
whose ancestor is a tagged type whose No_Controlled_Parts aspect is False}
[of a composite type] are considered to have a controlled part.
AARM To Be Honest: If the ancestor of the generic derived type is class-wide,
the aspect in question belongs to the specific type associated with the
class-wide type.
!discussion
This AI is a companion to AI12-0404-1. That AI contains wording changes only,
where no meaning (semantics) is intended to be changed. This AI contains cases
where there is new or changed semantics.
(1) (See proposal.)
(2) The alternative of checking all aspect definitions and changing those
that need definitions (or rules against specifications) would certainly
require too much change. Ada 95 had rules preventing the specification of
attributes for both renames and generic formal parameters, so the original
aspects like Size and Alignment were not designed to support such usages.
(3) For a formal derived type, only ancestor types that are tagged types that
have No_Controlled_Parts False could cause a problem. Untagged types cannot
add components, so it is obvious from the ancestor type whether any controlled
types are involved. And of course if No_Controlled_Parts is true for the
ancestor, then there are no controlled components by definition.
The generic body rule does not use our usual wording, which is messy but
takes into account the possibility of nested or child generics. We change it
to use that.
!corrigendum 13.1.1(17/3)
Replace the paragraph:
There are no language-defined aspects that may be specified on a renaming_declaration,
a generic_formal_parameter_declaration, a subunit, a package_body,
a task_body, a protected_body, or a body_stub other than a
subprogram_body_stub.
by:
Unless otherwise specified for a specific aspect, a language-defined aspect
cannot be specified on a renaming_declaration or a
generic_formal_parameter_declaration.
!corrigendum A.5.6(0)
@insc
See the conflict file for the changes.
!corrigendum A.5.7(0)
@insc
See the conflict file for the changes.
!corrigendum H.7.1(0)
@insc
See the conflict file for the changes.
!corrigendum H.4.1(0)
Insert new clause:
Static Semantics
For a type, the following type-related, representation aspect may be specified:
- No_Controlled_Parts
-
The type of this aspect is Boolean. If True, the type and any
descendants shall not have any controlled parts. If specified, the
value of the expression shall be static. If not specified, the value of
this aspect is False.
Legality Rules
If No_Controlled_Parts is True for a type, no component of the type
shall have a controlled part nor shall the type itself be controlled. For the
purposes of this rule, a type has a controlled part if its full type has a
controlled part; this is applied recursively. In
addition to the places where Legality Rules normally apply (see 12.3), this
rule also applies in the private part of an instance of a generic unit.
When enforcing the above rule within a generic body G or within the body of
a generic unit declared within the declarative region of generic unit G, a
generic formal private type of G and a generic formal derived type of G
whose ancestor is a tagged type whose No_Controlled_Parts aspect is False
are considered to have a controlled part.
!ASIS
No ASIS effect.
!ACATS test
ACATS B- and C-Tests are needed to check that the new capabilities are
supported.
!appendix
From a private conversation:
Arnaud Charlet: We forgot to use AI12-0394-1 in the Big_Real package.
We need to add a two parameter From_String to Big_Real.
Steve Baird: It's bizarre to call a routine with TWO String parameters
"From_String".
Tucker Taft: The name has to be the same as the one parameter version.
Randy Brukardt: "From_String" seems strange to me as well. Perhaps we
should call it From_Literal, with a renaming from From_String for
the one parameter version and an expression function for the
two parameter version.
Steve Baird: From_Literal doesn't help, only the one parameter version has
anything to do with literals and that's loose (the compiler has already
converted them to a string before these routines get called). How about
calling them From_Text?
Tucker Taft: That's hardly different than From_String in my mind. How about
From_Universal_Integer and From_Universal_Real? The length of the names
of these functions doesn't matter much, since they are mainly compiler-
generated calls. Perhaps From_Universal would be better, since that
would be the same for both packages.
Steve Baird: There's no universals anywhere to be seen for these functions,
so From_Universal doesn't do it for me. How about From_Universal_Image?
All: Yea, verily!
****************************************************************
From the AARM review of Jeff Cousins (September 2020).
13.1.1 (38.m/5) Says formal parameters removed from the list of entities
without language-defined aspects, but they look to still be there in
13.1.1 (4.c/5) (though the mention in (17/5) has gone – indeed the whole
of (17/5) has gone).
****************************************************************
From: Randy Brukardt
Sent: Tuesday, November 3, 2020 8:51 PM
The list in 13.1.1 (4.c/5) was previously fixed (a number of mistakes were
found, that being one), but since draft 26 came out. The remaining operative
parts of 13.1.1(17/5) were moved to 13.1.1.(18/5).
I'm a bit worried that the removal of the 13.1.1(17/5) formal parameter part
might start allowing aspect specifications for other existing language-defined
aspects. With that rule gone, we have to look at the entire list of aspects
(and attributes) to ensure that none of them could be used on a generic formal.
The whole reason we had this rule was because that was too hard to do.
So I wonder if we would be better served replacing 13.1.1(17/5) as a default
for formals and renamings:
Unless otherwise specified for a specific aspect, a language-defined aspect
cannot be specified on a @fa<renaming_declaration> or a
@fa<generic_formal_parameter_declaration>.
(We don't want Size or Pre or Pack or many others specified on renamings or on
formals, as we don't have any sort of matching rules.)
****************************************************************
From: Tucker Taft
Sent: Wednesday, November 4, 2020 6:14 AM
I agree with all of your dispensations for Jeff's comments. ...
****************************************************************
Summary of private mail, October 21-22, 2020.
Steve Baird:
uppose user X asserts that the following example is illegal because the element
type of T2 is controlled:
with Ada.Finalization;
package Pkg1 is
type T1 is private;
private
type T1 is new Ada.Finalization.Controlled with null record;
end Pkg1;
with Pkg1;
package Pkg2 is
type T2 is array (Boolean) of Pkg1.T1 with No_Controlled_Parts;
end;
But then user Y responds "No, T2's element type isn't controlled - as seen
from the point where the No_Controlled_Parts rule is enforced, the element
type is an untagged private type. So the example is legal." .
It seems to me that X's interpretation is pretty clearly what was intended,
but Y's interpretation is what you get from a strict reading of the existing
RM wording.
Is there a problem here?
Tucker Taft:
Yes. How do your recommend we fix it?
Actually, since this is a restriction, we generally allow these things to
see through privacy. Wouldn't that simplify things substantially?
Randy Brukardt:
As Steve said, it's not a restriction, it's an operational attribute. But
I'm not sure why it's operational, it has more in common with representation
attributes, I'd think, and those generally ignore privacy as well.
Tucker Taft:
If by making it a representation aspect we eliminate most of this complexity,
I am all in favor. It is effectively a restriction -- it doesn't introduce
or override any existing implicit operation on the type -- it merely makes
certain otherwise legal programs illegal. There is nothing particularly
"operational" about it.
Steve Baird:
== start digression #1 ==
I see another H.4.1 problem. We've got
When enforcing the above rule within a generic body, a generic formal
private type and a generic formal derived type of a composite type
are considered to have a controlled part.
Seems like "generic formal derived type" should be "generic formal derived
TAGGED type".
But because this aspect is nonoverridable, we also want to allow a formal
derived tagged type if the No_Controlled_Parts aspect of the ancestor type
is True. So that change (by itself) isn't quite right.
== end digression #1 ==
Randy Brukardt:
Can't an untagged composite type have controlled components? That has to be
covered for generic derived types. You could exclude elementary ancestors,
I guess.
Steve Baird:
In the untagged case, derivation cannot add new controlled components that
were not already present in the ancestor type.
If a formal untagged derived type does not appear to have any controlled
parts, then the actual parameter for a particular instance isn't going to
provide any unpleasant surprises.
Steve Baird:
== start digression #2 ==
We've got (in H.4.1)
When enforcing the above rule within a generic body, a generic formal
private type and a generic formal derived type of a composite type
are considered to have a controlled part.
Should that rule be limited to generic formal types of the generic whose body
we are within (as opposed to formals of other generics)?
== end digression #2 ==
Randy Brukardt:
You can be inside of multiple generic bodies at the same time, because of
nested generic units or even child generic units. All of our
wording uses plural for that reason. Perhaps you are complaining that we
didn't use *exactly* the magic words we used elsewhere. Specifically:
"Additionally, if <something> occurs within the body of a generic unit G or
within the body of a generic unit declared within the declarative region of
generic unit G, then ..."
Here's my try at the fixes needed:
(1) Change this to a representation aspect.
Delete H.4.1(3/5) ["nonoverridable" is only defined for operational aspects.
But this is a Boolean aspect subject to blanket rules like Atomic and Pack and
many other aspects that prevent it from being specified False for derived
types that have an ancestor that specify it True. Representation aspects have
detailed inheritance rules. Do we need anything else??]
(2) Modify H.4.1(4/5):
If No_Controlled_Parts is True for a type, no component of the type shall have
a controlled part nor shall the type itself be controlled. {For the purposes
of this rule, a type has a controlled part if its full type has a controlled
part; this is applied recursively.} In addition to the places where Legality
Rules normally apply (see 12.3), this rule also applies in the private part of
an instance of a generic unit.
Add an AARM note:
AARM Discussion: Like most representation aspects, this check breaks privacy
by looking at the full definition of all of the types involved.
(3) Modify H.4.1(5/5):
When enforcing the above rule within a generic body {G or within the body of
a generic unit declared within the declarative region of generic unit G}, a
generic formal private type {of G} and a generic formal derived type {of G
whose ancestor is a tagged type whose No_Controlled_Parts aspect is False}
[of a composite type] are considered to have a controlled part.
AARM To Be Honest: If the ancestor of the generic derived type is class-wide,
the aspect in question belongs to the specific type associated with the
class-wide type.
------------
Addendum, November 23, 2020
The reason that we had No_Controlled_Parts as operational was so that it
could be visibly specified on a private type. The reason that we had
No_Contolled_Parts as nonoverridable was to deal with the conflicting
progenitor problem. (We don't care about breaking privacy for the aspect,
since we're doing that in any case, but it would be too painful to
define a separate set of rules just for this aspect.)
As such, I've removed those changes from the proposal.
****************************************************************
Questions? Ask the ACAA Technical Agent