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

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

--- ai12s/ai12-0191-1.txt	2019/02/23 01:05:41	1.6
+++ ai12s/ai12-0191-1.txt	2019/02/23 02:13:57	1.7
@@ -1,4 +1,4 @@
-!standard 3.9.1(4.1/2)                                      19-02-12  AI12-0191-1/03
+!standard 3.9.1(4.1/2)                                      19-02-20  AI12-0191-1/04
 !standard 7.3.2(10.1/4)
 !standard 7.3.2(15/5)
 !class binding interpretation 16-06-06
@@ -31,7 +31,9 @@
   components that are not visible. On the other hand, a reference
   to the components of an object in a dynamic semantics rule would
   apply to all components of the object, visible or not, including
-  supplementary components (see 3.9.1).
+  (for tagged objects) components which are not components of the
+  the view of the object (this can occur when the tag of the
+  object does not match the tag of the type of the view of the object).
   Other terms, such as "subcomponent" and "part", are interpreted
   analogously.
 
@@ -41,12 +43,15 @@
   tagged type T1 or T1'Class and the (runtime) tag of X is T2'Tag,
   the components (if any) of X which are not components of T1
   (and which are not discriminants which correspond to a discriminant
-  of T1) are said to be "supplementary". For example, if T2 is an
+  of T1) are said to not be "components of the view of the object".
+  For example, if T2 is an
   undiscriminated extension of T1 which declares a component named Comp,
-  then X.Comp would be an supplementary component of X.
-  A part of an object is said to be either a *supplementary part* or
-  a *non-supplementary part* depending on whether it is a part of
-  a supplementary component of the object.
+  then X.Comp would not be a component of the view of X.
+  Similarly, a part of an object might or might not be a part of the
+  view of the object. [Redundant: A component of an untagged object, or
+  of a tagged object whose tag matches that of the type of the view of
+  the object, is always a component of the view of the object, even if
+  (for example) the view of the type of the object is a partial view.]
 
   AARM note: For example, there is a dynamic semantics rule that
   finalization of an object includes finalization of its components
@@ -57,31 +62,34 @@
      function Func return T1'Class is (T2'(others => <>));
      X : T1'Class := Func;
   the rule that "every component of the object is finalized" (as opposed to
-  something like "every non-supplementary component of the object is finalized")
+  something like "every component of the view of the object is finalized")
   means that the finalization of X will include finalization of X.Comp.
   For another example, see the rule about accessibility checking of
   access discriminants of parts of function results in 6.5.
   In contrast, the rules in 7.3.2 explicitly state that type invariant
-  checks are only performed for non-supplementary parts which are of the
-  type-invariant bearing type (as opposed to for all parts, supplementary
-  or not, which are of that type). Similarly, the rule in 13.13.2 governing
+  checks are only performed for parts which are of the type-invariant bearing
+  type and which are parts of the view of the object (as opposed to for all
+  parts, whether part of the view of the object or not, which are of that
+  type). Similarly, the rule in 13.13.2 governing
   which components of a composite value are read and written by the
   default implementations of Read and Write for a composite type states that
-  supplementary components are not read or written.
+  only the components of the view of the object are read or written.
 
 Modify 7.3.2(10.1/4):
 
    After successful explicit initialization of the completion of a deferred 
-   constant with a {non-supplementary} part of type T, if the completion is 
-   inside the immediate scope of the full view of T, and the deferred constant 
-   is visible outside the immediate scope of T, the check is performed on 
-   the {non-supplementary} part(s) of type T;
+   constant with a part of type T {that is a part of the view
+   of the object}, if the completion is inside the immediate scope of the 
+   full view of T, and the deferred constant is visible outside the immediate 
+   scope of T, the check is performed on the part(s) of type T{ that are
+   parts of the view of the object};
 
 Modify 7.3.2(15/5):
 
    Upon a successful return from a call on any subprogram or entry which is 
    type-invariant preserving for T, an invariant check is performed on each
-   {non-supplementary} part of type T which is subject to an invariant check for T.
+   part of type T{ that is a part of the view of the object} which is subject 
+   to an invariant check for T.
    In the case of a call to a protected operation, the check is performed 
    before the end of the protected action. In the case of a call to a task
    entry, the check is performed before the end of the rendezvous;
@@ -93,15 +101,17 @@
      some future extension component might have type T (contrast this to
      finalization, where we do intend that overhead). 
 with:
-     Reason: The various rules requiring type invariant checks for
-     non-supplementary parts of type T, as opposed to all parts of type T,
+     Reason: The various rules requiring type invariant checks only for
+     parts of type T which are parts of the view of the object, as opposed
+     to all parts of type T (whether part of the view of the object or not),
      are motivated by a desire to avoid overhead associated with the
      possibility that there *might* exist an extension of the tagged type
-     in question which has a part of type T.
+     in question that has a part of type T.
 
+
 Modify in 13.13.2(9/3):
-   ... the Write or Read attribute for each {non-supplementary} 
-   component is called ...
+   ... the Write or Read attribute for each component of the view
+   of the object is called ...
 
 !discussion
 
@@ -129,18 +139,6 @@
 needs to be performed for such components (e.g., finalization) will
 typically require dispatching.
 
-Probably the hardest question here is the choice of a term to refer
-to these hidden-but-we-don't-want-to-use-that-word components.
-For a view of an object X of a tagged type T1 whose
-underlying tag (i.e., the result of evaluating T1'Class (X)'Tag)
-is not T1'Tag, we are talking about the components of X which were
-declared in extensions of T1.
-
-Based on feedback from the group, the current write-up of the AI
-uses "supplementary". [Any of "concealed", "latent", or "undercover" (or
-even "screened", "sequestered", "cloaked", or "occulted") seem
-preferable to the AI author, but that's ok.]
-
 !example
 
 with Derived; use Derived;
@@ -475,5 +473,534 @@
        a tagged type are clarified.
 
 [This is version /03 of the AI - Editor.]
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, February 12, 2019  8:01 PM
+
+The term "supplementary" is growing on me.  The !discussion should still 
+come afterward.
+
+I am somewhat worried we are combining the rules for class-wide objects
+with the rules for "shortened" specific views of objects.  By "shortened" I 
+mean a specific view of a type extension like T2 through a T1 "lens," where T1
+is an ancestor of T2.  A class-wide view and a "shortened" view generally seem
+to behave pretty differently.  For example on assignment, clearly you finalize 
+the whole left-hand side in the case of a class-wide assignment, but for a 
+"shortened" specific view, I would think the "supplementary" components are 
+completely untouched as far as finalization and adjustment.  Is there really 
+*any* case where for a shortened view, we touch the supplementary components?
+
+For type invariants, we have an elaborate set of rules on type conversions, 
+so that we start looking at the masked components (hmm -- "masked" vs. 
+"supplementary"?) as we unwind the conversions.  But when you have the 
+shortened view, you don't do anything with those supplementary/masked 
+components.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, February 12, 2019  9:03 PM
+
+How about "masked" vs. "unmasked" components?
+Not sure if it is better...
 
-***************************************************************
+****************************************************************
+
+From: Steve Baird
+Sent: Tuesday, February 12, 2019  9:12 PM
+
+I prefer "masked" to "supplementary".
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, February 12, 2019  9:22 PM
+
+Of course, if the concern is about implying something about visibility,
+"screened" or "masked" certainly have that flavor, while "supplementary"
+does not.
+
+The correct flavor would be more like "unknown components", since they are 
+completely unknown to the implementation at the interesting point. "Unknown"
+doesn't appear in my thesaurus, someone else will have to look for 
+alternatives to that...
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, February 12, 2019  9:29 PM
+
+> I am somewhat worried we are combining the rules for class-wide 
+> objects with the rules for "shortened" specific views of objects.  By 
+> "shortened" I mean a specific view of a type extension like T2 through 
+> a T1 "lens," where T1 is an ancestor of T2.  A class-wide view and a 
+> "shortened" view generally seem to behave pretty differently.  For 
+> example on assignment, clearly you finalize the whole left-hand side 
+> in the case of a class-wide assignment, but for a "shortened"
+> specific view, I would think the "supplementary" components are 
+> completely untouched as far as finalization and adjustment.  Is there 
+> really *any* case where for a shortened view, we touch the 
+> supplementary components?
+
+Dunno. I didn't know/remember that assignment isn't supposed to finalize such
+components. I doubt that there is any ACATS test like that (assignments to 
+[entire] tagged objects are rare in real code) -- I wonder if anyone gets that 
+right?
+
+> For type invariants, we have an elaborate set of rules on type 
+> conversions, so that we start looking at the masked components (hmm -- 
+> "masked" vs. "supplementary"?) as we unwind the conversions.  But when 
+> you have the shortened view, you don't do anything with those 
+> supplementary/masked components.
+
+But specifically for type conversions, if you have a class-wide view (that 
+is, T'Class) in the spec of an invariant-preserving , then you want to check 
+the T components (only). That is what is different here, I think.
+
+If that's not the case, then there's an argument that there never was a bug 
+in the first place. That is, the (dynamic) components are *always* those of 
+the view of the object (where the runtime view ignores any privacy). When 
+one finalizes a stand-alone object or component of such an object, you always 
+have the original view of that object/component, so of course you can see all 
+of the subcomponents. And if you always see all of the components of a 
+class-wide object, then QED (since that would cover any "interesting"
+deallocations).
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, February 13, 2019  11:02 AM
+
+> But specifically for type conversions, if you have a class-wide view 
+> (that is, T'Class) in the spec of an invariant-preserving , then you 
+> want to check the T components (only). That is what is different here, I 
+> think.
+
+I am not convinced we have this right.  In my understanding of the intent, 
+any class-wide object is presumed to satisfy all of its invariants.  Another 
+way of thinking about it is when you create a class-wide object, you are 
+effectively passing outside of the package barrier, and you must be sure the 
+object satisfies all invariants that apply to it.
+
+> If that's not the case, then there's an argument that there never was 
+> a bug in the first place. That is, the (dynamic) components are 
+> *always* those of the view of the object (where the runtime view 
+> ignores any privacy). When one finalizes a stand-alone object or 
+> component of such an object, you always have the original view of that 
+> object/component, so of course you can see all of the subcomponents. 
+> And if you always see all of the components of a class-wide object, then 
+> QED (since that would cover any "interesting" deallocations).
+
+Class-wide objects generally worry about all of their components.  The weird 
+case is an object of a specific type, that was produced by doing a view 
+conversion on an object with more components.  These are the real oddball 
+guys, and we need to decide how these are to be handled.
+
+****************************************************************
+
+From: Steve Baird
+Sent: Wednesday, February 13, 2019  12:29 PM
+
+> For example on assignment, clearly you finalize the whole left-hand 
+> side in the case of a class-wide assignment, but for a "shortened" 
+> specific view, I would think the "supplementary" components are completely
+> untouched as far as finalization and adjustment.
+
+That's certainly true, but maybe this ought to be stated more clearly (perhaps 
+in an AARM note) in the section on assignment statements. If we want to do 
+that, that should probably be included in this AI.
+
+> Is there really *any* case where for a shortened view, we touch the 
+> supplementary components?
+I can't think of any. The two cases that came to mind are finalization and 
+the accessibility checks for access discriminants of a function result. But 
+if the function result type is specific then there are no supplementary 
+components of the function result object. And the cases where we get 
+"shortened" views of longer objects (e.g., via parameter passing or 
+View_Conversion'Access) are not cases where exiting a scope causes 
+finalization of that shortened object.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, February 13, 2019  1:23 PM
+
+>I am not convinced we have this right.  In my understanding of the intent, 
+>any class-wide object is presumed to satisfy all of its invariants.  Another 
+>way of thinking about it is when you create a class-wide object, you are 
+>effectively passing outside of the package barrier, and you must be sure the 
+>object satisfies all invariants that apply to it.
+
+See AARM 7.3.2(20.a/4) for this "intent":
+
+Reason: Class-wide objects are treated as though they exist outside the scope 
+of every type, and may be passed across package "boundaries" freely without 
+further invariant checks.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, February 13, 2019  3:50 PM
+
+>See AARM 7.3.2(20.a/4) for this "intent":
+>
+>Reason: Class-wide objects are treated as though they exist outside the
+>scope of every type, and may be passed across package "boundaries" freely 
+>without further invariant checks.
+
+This note is on class-wide types that are in the tree-of-T. These are 
+invariants that the package reasonably could know about. 
+
+But Steve has pointed out this also happens in the case of extensions of 
+otherwise unrelated types that contain objects of T. This intent is not 
+covered by any current invariant checks, since nothing class-wide related to T 
+is involved.
+
+In the somewhat pathological case that the body has sufficient visibility to 
+such an extension to pass/assign it an unchecked T, preventing that requires 
+a dispatching check. Or some other substantial change to the model.
+
+Since this case requires contortions, we don't want to require implementations 
+to check it, but would rather would describe it as a hole.
+At least that has been my understanding.
+
+Steve shows the case in interest in the e-mail:
+
+  procedure Type_Invariant_Breaker is
+
+   type Root is tagged null record;
+
+    package Pkg is
+       type Has_Invariant is private;
+
+       procedure Oops (X : in out Root'Class);
+       procedure Rely_On_Incoming_Invariant (Y : Has_Invariant);
+    private
+       type Has_Invariant is record Lo, Hi : Integer := 0; end record
+	with Type_Invariant => (Has_Invariant.Lo <= Has_Invariant.Hi);
+    end Pkg;
+
+    type Ext is new Root with
+      record Field : Pkg.Has_Invariant; end record;
+
+    package body Pkg is
+       procedure Break_It (Xx : out Has_Invariant) is
+       begin
+	    Xx := (Lo => 1, Hi => 0);
+       end;
+
+       procedure Oops (X : in out Root'Class) is
+       begin
+	 if X in Ext'Class then
+	    Break_It (Ext (X).Field);
+	 end if;
+       end;
+
+       procedure Rely_On_Incoming_Invariant (Y : Has_Invariant) is
+       begin
+	 pragma Assert (Y.Lo <= Y.Hi);
+       end;
+    end Pkg;
+
+    Ext_Var : Ext;
+  begin
+    Pkg.Oops (Ext_Var);
+    Pkg.Rely_On_Incoming_Invariant (Ext_Var.Field);
+  end;
+
+I was thinking a case with an interface:
+
+    package Pkg2 is
+       type Has_Invariant is private;
+
+       procedure Rely_On_Incoming_Invariant (Y : Has_Invariant);
+
+       type Some_Interface is interface;
+       procedure Munge (I : in out Some_Interface; Z : Has_Invariant) is abstract;
+
+       procedure Oops (X : in out Some_Interface'Class);
+
+    private
+       type Has_Invariant is record Lo, Hi : Integer := 0; end record
+	with Type_Invariant => (Has_Invariant.Lo <= Has_Invariant.Hi);
+    end Pkg2;
+
+    package body Pkg2 is
+       procedure Break_It (Xx : out Has_Invariant) is
+       begin
+  	    Xx := (Lo => 1, Hi => 0);
+       end;
+
+       procedure Oops (X : in out Some_Interface'Class) is
+          Bad : Has_Invariant;
+       begin
+          Break_It (Bad);
+          X.Munge (Bad);
+       end;
+    end Pkg2;
+
+Here, the implementation of Munge (which is not related at all to the package, 
+and thus will not be checking any invariants) can save Bad into an extension 
+of X. Oops in theory should be checking that part when it exits, but there is 
+no way for that to happen short of there being a dispatching routine that 
+knows about all of the components of each extension of Some_Interface. (Again, 
+Some_Interface itself is not related to T in any way.)
+
+---
+
+I also note that the original question was about "parent part", and was posed 
+by one Tucker Taft. I'm not sure why this matters (the "parent part" is not a
+"part" in the technical sense of "object or its components"), but I can see 
+why it would confuse.
+ 
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, February 13, 2019  6:25 PM
+
+> Here, the implementation of Munge (which is not related at all to the 
+> package, and thus will not be checking any
+> invariants) can save Bad into an extension of X. Oops in theory should 
+> be checking that part when it exits, but there is no way for that to 
+> happen short of there being a dispatching routine that knows about all 
+> of the components of each extension of Some_Interface. (Again, 
+> Some_Interface itself is not related to T in any
+> way.)
+
+You might want to claim that Munge should check the invariant (inbound) because 
+the dispatching is to an abstract routine that is itself "invariant-preserving".
+I think that's arguable, but in any case, if we change Munge to a function, it 
+becomes irrelevant (invariants of inbound "in" parameters of functions are 
+never checked). (And even if the invariant is checked in the procedure case, 
+the object X is modified before the failure, meaning that the "leak" has 
+already happened.)
+
+One could also create this case by using two interfaces, I1 and I2, with I2 a 
+descendant of I1, I2 being in a separate package C1 and containing the Munge 
+operation (which is therefore not invariant-preserving itself). If the body 
+of the invariant-containing package Pkg2 withs C1, it can dispatch to the 
+Munge operation, and again we can have a leak.
+
+As with all permitted holes in invariant protection, this sort of issue 
+requires active participation of the package containing the invariant, so 
+there is no reason to pay the steep cost to fix it. But we also want to ensure 
+that (A) no one thinks that they have to implement such a check; and
+(B) that we include it in the list of holes. Both of these require a 
+reasonable definition of what is *not* checked.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, February 13, 2019   6:47 PM
+
+...
+> Of course, if the concern is about implying something about 
+> visibility, "screened" or "masked" certainly have that flavor, while 
+> "supplementary"
+> does not.
+> 
+> The correct flavor would be more like "unknown components", since they 
+> are completely unknown to the implementation at the interesting point. 
+> "Unknown"
+> doesn't appear in my thesaurus, someone else will have to look for 
+> alternatives to that...
+
+I just ran across a thesaurus in LibreOffice (never thought to look there),
+and it is happy to give alternatives to "unknown":
+
+"unmapped"
+"unbeknownst"
+"unheard-of"
+"unacknowledged"
+"unfamiliar"
+"dishonorable" :-)
+"unidentified"
+"anonynous" (um, no.)
+"unsuspected"
+"obscure"
+"unsung"
+"terra incognita" :-) :-)
+"stranger"
+"alien"
+"variable" (um, really no.)
+
+I have some favorites here, both serious and not so serious. Not sure how the 
+rest of us feel.
+
+****************************************************************
+
+From: Tullio Vardanega
+Sent: Thursday, February 14, 2019  2:17 AM
+
+Seems like "obscure", to me.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, February 14, 2019  7:39 AM
+
+Here are two other pairs:
+
+   *Overt* components, and *latent* components, of the current view.
+
+   Components *included* in the current view, components *excluded* from the 
+   current view.
+
+I think it is worth using the term "view" when talking about this distinction, 
+because it really is all about the view, not about the underlying object.
+
+****************************************************************
+
+From: Edmond Schonberg
+Sent: Thursday, February 14, 2019  9:43 AM
+
+“Overt” seems perfect. Maybe “implicit” instead of latent?
+
+****************************************************************
+
+From: Jean-Pierre Rosen
+Sent: Thursday, February 14, 2019  9:54 AM
+
+> I think it is worth using the term "view" when talking about this 
+> distinction, because it really is all about the view, not about the 
+> underlying object.
+
+Agreed, but if a full phrase is acceptable, then "components that are/are not
+part of the current view" would exactly describe what we mean.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, February 14, 2019  11:16 AM
+
+>“Overt” seems perfect. Maybe “implicit” instead of latent?
+
+Alas, Ada already refers to the "implicit" components of a task or protected 
+object, to represent entry queues.  And implicit is already pretty heavily 
+used for "implicit declarations" of inherited operations.  I like "latent" in 
+the sense of a "latent talent."  It is there, but it just hasn't yet been 
+brought forward.
+
+****************************************************************
+
+From: Steve Baird
+Sent: Thursday, February 14, 2019  11:54 AM
+
+I agree.
+
+I don't think an antonym of "active" would be confusing even though we already 
+have active priorities, active partitions, active locales, and active tasks.
+
+Interestingly, a variant part does not have an active variant; other 
+terminology was used for that.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, February 14, 2019  12:52 PM
+
+Yes.  Let's leave "active" for something relating to tasks.
+
+****************************************************************
+
+From: Gary Dismukes
+Sent: Thursday, February 14, 2019  12:49 PM
+
+> Alas, Ada already refers to the "implicit" components of a task or protected 
+> object, to represent entry queues.  And implicit is already pretty heavily 
+> used for "implicit declarations" of inherited operations.  I like "latent" 
+> in the sense of a "latent talent."  It is there, but it just hasn't yet been
+> brought forward.
+
+I had thought of mentioning "latent" at the meeting (as well as "concealed"), 
+but didn't because it seemed to have too much of the sense of hidden, which 
+was objected to.  I would be OK with that choice, but J-P's suggestion along 
+the lines of "components that are part of the current view" seems reasonable, 
+and would avoid the need to introduce another new term.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, February 14, 2019  1:24 PM
+
+> I had thought of mentioning "latent" at the meeting (as well as 
+> "concealed"), but didn't because it seemed to have too much of the 
+> sense of hidden, which was objected to.
+
+"Latent" doesn't imply any sort of hiding in my view.  It just means it hasn't
+been recognized yet.
+
+> I would be OK with that choice, but J-P's suggestion along the lines 
+> of "components that are part of the current view" seems reasonable, 
+> and would avoid the need to introduce another new term.
+
+I agree, it may be that if we use the term "current view" explicitly, that 
+everything will be quite clear -- "part of the current view," "a component of 
+the current view," etc. all seem pretty clear.
+
+****************************************************************
+
+From: Steve Baird
+Sent: Thursday, February 14, 2019  3:22 PM
+
+> I agree, it may be that if we use the term "current view" explicitly, that 
+> everything will be quite clear -- "part of the current view," "a component 
+> of the current view," etc. all seem pretty clear.
+
+I'll take another look at the AI with this approach in mind.
+
+****************************************************************
+
+From: Steve Baird
+Sent: Thursday, February 21, 2019  9:56 PM
+
+I have attached two versions of this AI using the approach suggested by 
+Jean-Pierre that Tuck referred to above.
+
+I like the idea of using a phrase instead of a single word to capture the 
+property in question, but I don't like the suggested phrase.
+
+Nonetheless, in the attached v3 version (which I do not endorse) I used the 
+suggested phrase.
+
+[This is version /04 of the AI - Editor.]
+
+It seems wrong to say that (by definition!) in a situation like
+
+    package P1 is
+       type T1 is private with Type_Invariant => ... ;
+
+       package P2 is
+         type T2 is private;
+       private
+         type T2 is record T1_Comp : T1; end record;
+       end P1;
+
+       procedure Foo (X : out P2.T2);
+    private
+       ...
+    end P1;
+
+when we are deciding what type invariant checks to perform as part of a return
+from Foo, X.T2 is a component of the view of X.
+
+To me, it seems clear that if we are at a point when we can see only the 
+partial view of P2.T2, then saying that X.T2 is a component of the view of X 
+will lead to confusion or worse.
+
+So I used a different phrase in the attached v4 variant ("hidden by the 
+nominal tag").
+
+[This is version /05 of the AI - Editor.]
+
+That's the one I endorse, although others might suggest better phrases now 
+that we seem to have given up on single words like "latent" or "screened".
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, February 21, 2019  11:02 AM
+
+****************************************************************

Questions? Ask the ACAA Technical Agent