CVS difference for ai12s/ai12-0155-1.txt

Differences between 1.5 and version 1.6
Log of other versions for file ai12s/ai12-0155-1.txt

--- ai12s/ai12-0155-1.txt	2015/04/03 05:47:37	1.5
+++ ai12s/ai12-0155-1.txt	2015/06/02 03:27:47	1.6
@@ -1,4 +1,6 @@
-!standard 13.14(3/4)                                   15-04-02  AI05-0155-1/04
+!standard 3.10.1(10/3)                                   15-06-01  AI05-0155-1/05
+!standard 13.14(3/4)
+!standard 13.14(15.1/3)
 !class binding interpretation 15-02-20
 !status work item 15-02-20
 !status received 15-02-20
@@ -8,8 +10,9 @@
 !subject Freezing of operations of incomplete types with completions deferred to a body
 !summary
 
-When a profile is frozen at the end of a declarative part or package
-specification, any incomplete types that the profile contains are not frozen.
+Incomplete types are never frozen; Legality Rules prevent all possible problems
+with them. (The completion of an incomplete type freezes in the normal way,
+of course.)
 
 !question
 
@@ -61,32 +64,53 @@
 
 !wording
 
+Add after 3.10.1(10/3):
+
+  The controlling operand or controlling result of a dispatching call shall
+  not be of an incomplete view if the operand or result is dynamically tagged.
+
+  AARM Discussion:
+  This rule is needed to prevent the following case:
+
+     package Pack is 
+        type T is tagged; 
+        function F return access T'Class; 
+        function G (X : access T) return Integer; 
+        I : Integer := G (F);                 -- Illegal by above rule.
+        type T is tagged null record; 
+     end Pack;
+
+  If this was not illegal, the compiler would have to generate a dispatching
+  call on G without necessarily knowing where the tag of type T is stored
+  (the completion of T might not be until the body of Pack). The fact that any
+  such call will raise Program_Error does not absolve us of detecting the
+  problem; see the Language Design Principles in 13.14.)
+
+[Editor's note: I made the rule as narrow as possible in order to avoid any
+compatibility issues. If the call to G had been statically tagged, there is no
+problem since the tag of the operand need not be read.]
+
 Modify 13.14(3/4):
+
+  The end of a declarative_part, protected_body, or a declaration of a library
+  package or generic library package, causes freezing of each entity and
+  profile declared within it[, except for incomplete types]. A proper_body,
+  body_stub, or entry_body causes freezing of each entity and profile declared
+  before it within the same declarative_part[ that is not an incomplete type;
+  it only causes freezing of an incomplete type if the body is within the
+  immediate scope of the incomplete type].
+
+Add after 13.14(15.1/3):
+
+  Notwithstanding the rest of this subclause, freezing an incomplete view has
+  no effect.
+
+  AARM Ramification: In particular, there is no requirement on the completion
+  when an incomplete type would have been frozen. Once the completion of the
+  incomplete type is seen, any further references to the type will be of the
+  complete type, which will be frozen in the normal way. Legality Rules prevent
+  all problems for incomplete types themselves.
 
-The end of a declarative_part, protected_body, or a declaration of a library
-package or generic library package, causes freezing of each entity and profile
-declared within it, except for incomplete types. A proper_body, body_stub, or
-entry_body causes freezing of each entity and profile declared before it within
-the same declarative_part that is not an incomplete type; it only causes
-freezing of an incomplete type if the body is within the immediate scope of the
-incomplete type. {Freezing of a profile in these cases does not freeze an incomplete
-subtype of the profile.}
-
-Modify 13.14(10.2/4):
-
-At the place where a generic_instantiation causes freezing of a callable entity,
-the profile of that entity is frozen unless the formal subprogram corresponding
-to the callable entity has a parameter or result of a formal untagged incomplete
-type; if the callable entity is an expression function, the return expression
-expression of the expression function causes freezing{; if the formal subprogram
-corresponding to the the callable entity has a parameter or result of a formal
-incomplete type, freezing of a profile does not freeze an incomplete
-subtype of the profile}.
-
-AARM Reason: The last part only can apply if the parameter or result is a formal
-tagged incomplete type, as the entire profile is not frozen otherwise. We except
-incomplete types in this case so that calls that would be legal in a non-generic
-context can be used within a generic for a formal tagged incomplete type as well.
 
 !discussion
 
@@ -111,103 +135,40 @@
 
 ----
 
-The reason that we need to freeze incomplete types is discussed in AI05-0017-1.
-In particular, it's necessary to prevent premature dispatching calls for
-ordinary (not Taft-Amendment) incomplete types. (Taft-Amendment incomplete
-types can't have primitive operations, so no dispatching calls can be made
-on an operations of them.)
-
-Therefore, we only exclude freezing of incomplete types in contexts where
-no further premature calls can be made (the "global freezing contexts"), or
-dispatching calls are impossible for other reasons.
-
-We have to make similar exceptions for generic instantiations, so that one
-can wrap code in a generic without it becoming illegal when instantiated.
-Luckily, normal generic formal subprograms are never dispatching, and
-abstract formal subprograms do not allow an incomplete controlling type.
-Thus, we don't need to freeze incomplete types here.
+In order to fix this hole, we could have made a bunch more exceptions as to
+where incomplete types are freezing. But that was getting more and more messy
+(changes to at least 13.14(3/4) and 13.14(10.2/3) would be required, and those
+are already messy).
+
+13.14(1.j/3) suggests that we wanted to only use Legality Rules for incomplete
+types and not treat them as freezing. But that's not how 13.14 was worded
+(there is no exception for incomplete types). Moreover, there is one known
+case, discussed in AI05-0017-1, where the Legality Rules are insufficient and
+freezing of incomplete types fixed any problems.
+
+Therefore, we need to add a Legality Rule to 3.10.1 to cover those cases. Once
+we have that, there is no need to ever freeze an incomplete view, and thus
+we add a rule to explicitly state that.
+
+We simplify the wording of 13.14(3/4) to eliminate all mentions
+of incomplete types or views, as those are covered by the new notwithstanding
+rule. (The new notwithstanding rule also covers - at least - explicit uses as
+a name, and occurrences of incomplete views in profiles.)
+
+[Note to Tucker: An alternative approach would be to make different (fewer??)
+changes and just except incomplete views from freezing from the end of packages
+[already true], in profiles, and by explicit reference. Other sorts of uses
+(in object declarations, for instance) are already illegal. But this seems
+fragile in that anything I forgot about would still freeze the incomplete
+type (might be harmless, might not).]
+
+13.14(5/3) and 13.14(10.2/4) still need their mentions of formal incomplete
+types, as those are is mainly about not freezing private types when used as an
+actual, and not freezing the profile of an actual subprogram with private type
+parameters. The rules are not specifically about incomplete types.
 
 ----
 
-Notes on the 13.14(3/4) wording:
-
-We only need to say that incomplete types of the profile are not frozen. If
-the incomplete type is not one that is exempt from freezing, it will
-necessarily be frozen as well by one of these "global freezing contexts", and
-thus we don't need to specifically include those in profile freezing.
-
-The wording "subtype of a profile" seems a bit non-specific, but it echos the
-wording of 13.14(14/3) [which is the normal case for freezing a profile]. There
-is no reason for this to be different.
-
-----
-
-Notes on the 13.14(10.2/4) wording:
-
-We don't need to worry about which incomplete types are used in the profile,
-as any that don't correspond to a formal incomplete type will work as a
-similar parameter in a non-generic call. Either that's OK, or any such call
-would necessarily be illegal (if the incomplete type is untagged).
-
-[Note to Tucker: It might be the case that we could simply exclude any
-incomplete types from the profile of the actual, as it seems that any
-incomplete that would be legal would have had to have been declared outside
-of the generic, and that would work normally (whatever normally is). Such a
-case seems rather unlikely outside of ACATS tests and ARG examples, so
-perhaps the simpler wording is better.]
-
-[Note to Tucker II: The example that requires freezing is:
-
-   package Pack is 
-      type T is tagged; 
-      function F return access T'Class; 
-      function G (X : access T) return Integer; 
-      I : Integer := G (F); 
-      type T is tagged null record; 
-   end Pack;
-
-The call on F necessarily would fail an elaboration check (there is no legal
-expression that could be used in an expression function; an allocator would be
-premature and the prefix of 'Access cannot be incomplete). But the compiler
-still would have to generate code for a call without knowing where the tag is.
-
-This quite similar to the case described in the AARM, ending with AARM 13.14(i.u):
-"This is silly. If we're going to require compilers to detect the exception at 
-compile time, we might as well formulate the rule as a legality rule."
-
-However, there might be an alternative. We could adopt a Legality Rule stating
-that a dispatching call on an object of an incomplete type is illegal before
-a completion for an incomplete *type*. (We would not want such a rule to apply
-for an incomplete view, since those never require freezing, and it's not
-possible for any primitives to be imported that way anyway.) We already have a
-rule of that nature for Taft-Amendment types (any operations cannot be
-primitive), so it's not unprecedented.
-
-I don't think that there is a problem for untagged incomplete types (or, for
-that matter with tagged incomplete types that aren't dispatching). Direct uses
-of untagged incomplete types as parameters is illegal. Passing
-access-to-incomplete doesn't seem to cause any real problems (imagine the above
-example without "tagged"); a non-null value would have to have been created
-somewhere where the full definition is available, but if that is done, the
-call using access-to-incomplete doesn't need to look into it.
-
-[Bairdian aside: what happens if the access type has a discriminant constraint?
-Is that allowed? If it is, the check would need to know where the discriminants
-are, and that's not known until freezing. Janus/Ada has lots of bugs because of
-problems like that; I had to simply guess (based on what is known when the
-type is declared) and that got the ACATS to pass. But when I tried to do it
-right (raising an exception if an unfrozen discriminant was accessed), I wasted
-a week and got nowhere near getting anything to work. Took the check back out.
-End aside.]
-
-If we did that, then we could abandon any freezing of incomplete types
-(anywhere). Based on the AARM notes, that was the intended model for Ada 95.
-That probably would be simpler, but of course we'd have to let Steve tell us
-about all of the unlikely things that could happen. And that would be a lot
-more radical.]
-
-----
-
 The author created a complete ACATS-style test for an example like the one
 in the question. The test uses the operations in a child package where
 the completion is unknown. (This is usefully possible because the type
@@ -225,41 +186,11 @@
 Ada 2012 and Taft-Amendment types aren't that common, so most likely no one
 has yet run into the intersection of both.
 
-[Note to Tucker III: I can certainly live with not changing anything here,
+[Note to Tucker II: I can certainly live with not changing anything here,
 but then I certainly would want to have ACATS tests that ensure that the
 original example was detected as a freezing error. Else we have an "attractive
 hazard", something that looks like it should work, and might work on some
-compiler, but actually doesn't work. That probably goes for the entire
-instantiation of a generic with an incomplete type, too. (Banning that would
-certainly make Ed happier. I don't quite understand why that is so hard to
-implement, but of course things that should be easy can turn out hard in an
-existing implementation not prepared to handle it. Probably the hardest thing
-to make work in Janus/Ada would be "in out" parameters in functions, because
-the entire back-end assumes that a function does not need modify parameters
-after a call. That would be a very tough assumption to root out of the
-optimizer in particular.]
-
-----
-
-** Temporary (?) note **
-
-Calls in other units are OK, *assuming* that any entity imported via a *with*
-(or from a parent, which is another form of semantic dependence; those should
-all be treated equivalently) is already frozen (somewhere). That makes sense,
-as some other unit must have the completion or the partition is illegal.
-However, the language rules don't make this clear. It's definitely significant
-for various kinds of incomplete types -- we surely don't want anyone to think
-that incomplete views from a limited with need to have a completion visible
-somewhere in order to declare or call a subprogram, and the same is true for
-Taft-Amendment incomplete types. With that assumption, we don't need to fix
-the generic problem, although it means that a generic cannot be instantiated
-in the same scope as these operations. (Which is annoying, but not fatal, as
-the instance could have been in the child unit, where no freezing would
-apply [we assume!].)
-
-It's not clear to me whether we should attempt to fix this problem.
-
-** End Temporary (?) note **
+compiler, but actually doesn't work.]
 
 !corrigendum 13.14(3/4)
 

Questions? Ask the ACAA Technical Agent