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

Differences between 1.2 and version 1.3
Log of other versions for file ai12s/ai12-0199-1.txt

--- ai12s/ai12-0199-1.txt	2016/10/06 01:29:00	1.2
+++ ai12s/ai12-0199-1.txt	2016/11/15 01:10:52	1.3
@@ -1,5 +1,8 @@
-!standard 7.3.2(5/4)                                   16-10-05  AI12-0199-1/02
+!standard 7.3.2(5/4)                                   16-11-14  AI12-0199-1/03
+!standard 7.3.2(8/3)
 !class binding interpretation 16-07-21
+!status Amendment 1-2012 16-11-14
+!status ARG Approved 7-0-2  16-10-09
 !status work item 16-07-21
 !status received 16-06-11
 !priority Low
@@ -8,11 +11,11 @@
 !subject Abstract subprogram calls in class-wide invariant expressions
 !summary
 
-Do not apply class-wide type invariants to abstract types, to avoid
-various problems. Define the notion of a "corresponding expression" for
-a class-wide type invariant, replacing references to components as
-appropriate, taking into account rules for corresponding and specified
-discriminants.
+Class-wide type invariants do not apply to abstract types, to avoid various
+problems. Define the notion of a "corresponding expression" for a class-wide
+type invariant, replacing references to components as appropriate, taking into
+account rules for corresponding and specified discriminants when applying them
+to a nonabstract descendant.
 
 !question
 
@@ -25,9 +28,10 @@
     function F1 (X : Ifc) return Boolean is abstract;
   end Pkg;
 
-Does the call to F1 violate the rule against non-dispatching calls to abstract
+Does the call to F1 violate the rule against nondispatching calls to abstract
 subprograms?
-  (No, because aspect re-interpreted using notional, non-abstract descendant)
+  (No, because the aspect is reinterpreted using notional, nonabstract
+   descendant)
 
 !recommendation
 
@@ -48,11 +52,11 @@
   can be applied to this current instance are those defined for such a
   formal derived type.
 
-Modify 7.3.2(8):
+Modify 7.3.2(8/3):
   If the Type_Invariant'Class aspect is specified for a tagged type T,
-  then [the invariant expression applies to all descendants of T] {then
-  a /corresponding expression/ also applies to each non-abstract
-  descendant T1 of T [(including T itself if it is non-abstract)]}. {The
+  then [the invariant expression applies to all descendants of T] {a
+  /corresponding expression/ also applies to each nonabstract
+  descendant T1 of T [(including T itself if it is nonabstract)]}. {The
   corresponding expression is constructed from the associated expression
   as follows:
 
@@ -60,8 +64,12 @@
     replaced with references to the corresponding components of T1 (or
     to T1 as a whole).
 
+    AARM Ramification: The only nondiscriminant components visible at the
+    point of such an aspect specification are necessarily inherited from some
+    nonprivate ancestor.
+
   * References to discriminants of T are replaced with references to the
-    corresponding discriminant of T1 (see 3.7), or to the specified
+    corresponding discriminant of T1, or to the specified
     value for the discriminant, if the discriminant is specified by the
     derived_type_definition for some type that is an ancestor of T1 and
     a descendant of T (see 3.7).}
@@ -69,7 +77,7 @@
 !discussion
 
 For simplicity, we say that class-wide type invariants only apply to
-non-abstract types.  For an abstract type, no type invariant checks are
+nonabstract types.  For an abstract type, no type invariant checks are
 performed, nor should the type invariant expression be presumed true.
 
 This AI provides rules for class-wide type invariants analogous to those
@@ -84,7 +92,7 @@
 
       package Pkg2 is
          type T is tagged null record
-            with Type_Invariant'Class => Is_OK (X); -- OK.
+            with Type_Invariant'Class => Is_OK (X);
          function Is_Ok (X : T) return Boolean;
          procedure Proc (X : in out T);
       end Pkg2;
@@ -95,7 +103,7 @@
       with Pkg2;
       package Pkg3 is
          type NT is abstract new Pkg2.T null record;
-         -- inherits Type_Invariant'Class => Is_OK (X); -- Illegal.
+         -- inherits Type_Invariant'Class => Is_OK (X);
          function Is_Ok (X : NT) return Boolean is abstract;
          -- inherits Proc.
       end Pkg3;
@@ -109,6 +117,55 @@
 eliminates problems associated with type conversions to or across
 abstract types, and so on.
 
+!corrigendum 7.3.2(5/4)
+
+@drepl
+Within an invariant expression, the identifier of
+the first subtype of the associated type denotes the current instance
+of the type. Within an invariant expression for the Type_Invariant aspect
+of a type @i<T>, the type of this current instance is @i<T>. Within
+an invariant expression for the Type_Invariant'Class aspect of a type
+@i<T>, the type of this current instance is interpreted as though it
+had a (notional) type @i<NT> that is a visible formal derived type whose
+ancestor type is @i<T>. The effect of this interpretation is that the
+only operations that can be applied to this
+current instance are those defined for such a formal derived type.
+@dby
+Within an invariant expression, the identifier of
+the first subtype of the associated type denotes the current instance
+of the type. Within an invariant expression for the Type_Invariant aspect
+of a type @i<T>, the type of this current instance is @i<T>. Within
+an invariant expression for the Type_Invariant'Class aspect of a type
+@i<T>, the type of this current instance is interpreted as though it
+had a (notional) nonabstract type @i<NT> that is a visible formal derived
+type whose ancestor type is @i<T>. The effect of this interpretation is that
+the only operations that can be applied to this
+current instance are those defined for such a formal derived type.
+
+
+!corrigendum 7.3.2(8/3)
+
+@drepl
+If the Type_Invariant'Class aspect is specified for a tagged type @i<T>,
+then the invariant expression applies to all descendants of @i<T>.
+@dby
+If the Type_Invariant'Class aspect is specified for a tagged type @i<T>,
+then a /corresponding expression/ also applies to each nonabstract
+descendant @i<T1> of @i<T> (including @i<T> itself if it is nonabstract).
+The corresponding expression is constructed from the associated expression
+as follows:
+
+@xbullet<References to non-discriminant components of @i<T> (or to @i<T>
+itself) are replaced with references to the corresponding components of @i<T1>
+(or to @i<T1> as a whole).>
+
+@xbullet<References to discriminants of @i<T> are replaced with references to
+the corresponding discriminant of @i<T1>, or to the specified value for the
+discriminant, if the discriminant is specified by the
+@fa<derived_type_definition> for some type that is an ancestor of @i<T1> and
+a descendant of @i<T> (see 3.7).>
+
+
 !ASIS
 
 No ASIS effect.
@@ -180,17 +237,17 @@
 case, so we do have some limits.)
 
 The straighforward version of the 6.1.1(18.2/4) rule would be something like:
-A non-abstract type T is illegal if corresponding expression for a
+A nonabstract type T is illegal if corresponding expression for a
 Type_Invariant'Class or Post'Class aspect would be illegal.
 
 But that doesn't fix the bug (NT is abstract in the example above). And
-dropping "non-abstract" runs afoul of (1) above: it would make all invariants
+dropping "nonabstract" runs afoul of (1) above: it would make all invariants
 of interfaces illegal.
 
 It seems easy enough to craft a rule to plug this particular bug:
    If the corresponding class-wide invariant expression for an abstract type
    T contains a call to an abstract routine, then there cannot be any
-   non-abstract subprograms in the immediately enclosing scope (including in
+   nonabstract subprograms in the immediately enclosing scope (including in
    nested scopes) that have a parameter with a part of T.
 
 But that has issues:

Questions? Ask the ACAA Technical Agent