CVS difference for ai22s/ai22-0012-1.txt

Differences between 1.1 and version 1.2
Log of other versions for file ai22s/ai22-0012-1.txt

--- ai22s/ai22-0012-1.txt	2021/11/13 02:32:24	1.1
+++ ai22s/ai22-0012-1.txt	2021/11/14 06:16:23	1.2
@@ -1,30 +1,127 @@
-!standard 6.1.1(18.2/5)                               21-11-12  AI22-0012-1/00
+!standard 6.1.1(18.2/5)                               21-11-13  AI22-0012-1/01
 !class binding interpretation 21-11-12
 !status work item 21-11-12
 !status received 21-07-07
 !priority Medium
 !difficulty Hard
 !qualifier Error
-!subject Incompatibility with AI12-0412-1
+!subject Incompatibility for abstract type Pre'Class
 !summary
 
-** Tucker is promising a full write-up by Monday; I'll post it as soon
-   as possible. **
+The wording in 6.1.1(18.2/5) is adjusted to disallow only expressions
+containing nondispatching invocations of abstract functions, rather than
+requiring the expression to be static.
 
 !question
 
+If we declare an abstract type T0 with a nonabstract primitive Foo, with a 
+nonabstract Pre'Class invoking All_Good:
 
+   package P is
+        type T0 is abstract tagged private;
+        procedure Foo(X : T0) with Pre'Class => All_Good(X);
+
+        function All_Good(X : T0) return Boolean;
+   private
+       ...
+   end P;
+
+We then derive another type T1 from T0, and override the Foo primitive to call
+the primitive of its parent type, and then do something more:
+
+   with P;
+   package P1 is
+         type T1 is new T0 with private;
+
+         procedure Foo(X : T1);
+   private
+        ...
+   end P1;
+
+   package body P1 is
+         procedure Foo(X : T1) is
+         begin
+              P.Foo(T0(X));
+              ...
+         end Foo;
+   end P1;
+
+This was legal in Ada 2012, but would be illegal in Ada 2022 because of 
+6.1.1(18.2/5) which comes from AI12-0412-1.
+
+Should this be legal in Ada 2022?  (Yes.)
+
 !recommendation
+
+RM 6.1.1(18.2/5) currently says:
 
-(See Summary.)
+  If the primitive subprogram S is not abstract, but the given
+  descendant of T is abstract, then a nondispatching call on S is
+  illegal if any Pre'Class or Post'Class aspect that applies to S is
+  other than a static boolean expression. Similarly, a primitive
+  subprogram of an abstract type T, to which a non-static Pre'Class or
+  Post'Class aspect applies, shall neither be the prefix of an Access
+  attribute_reference, nor shall it be a generic actual subprogram for a
+  formal subprogram declared by a
+  formal_concrete_subprogram_declaration.
+
+Note the use of "static" rather than "nonabstract" in the above
+paragraph. Originally this was thought to be a corner case, so an
+easier rule was proposed. But there are users who have already bumped
+into this incompatibility using an early implementation of Ada 2022.
 
+The wording should be fixed to avoid this incompatibility.
+
 !wording
 
+Modify 6.1.1(18.2/5) as follows:
+
+  If the primitive subprogram S is not abstract, but the given
+  descendant of T is abstract, then a nondispatching call on S is
+  illegal if {the corresponding expression for} any Pre'Class or
+  Post'Class aspect that applies to S [is other than a static boolean
+  expression]{includes a nondispatching invocation of an abstract
+  function}. Similarly, a primitive subprogram of an abstract type T, to
+  which [a non-static]{such a} Pre'Class or Post'Class aspect applies,
+  shall neither be the prefix of an Access attribute_reference, nor
+  shall it be a generic actual subprogram for a formal subprogram
+  declared by a formal_concrete_subprogram_declaration.
+
 !discussion
 
+This incompatibility was introduced by AI12-0412-1. The goal was to
+allow an abstract class-wide pre/post on a non-abstract function,
+presuming that the abstract pre/post functions would be overridden in a
+descendant. Unfortunately, there is an incompatibility for a case where
+there is an abstract type with a nonabstract primitive, with
+*nonabstract* class-wide pre/post. AI12-0412-1 made it illegal to call
+such a subprogram using a non-dispatching call, if the class-wide
+pre/post was *nonstatic*. In Ada 2012, calling such a subprogram was
+legal.
+
+Note that this situation can occur not only when the Pre'Class or
+Post'Class is first resolved -- the problem can occur any time that an
+abstract routine is *bound* (even if the resolved routine is not
+abstract, since remember that this is talking about the nominal NT, but
+ultimately one can bind to a derived type with an abstract version of
+one of the included functions).
+
+Note that the following was added into the AARM for Ada 2022, after
+6.1.1(18.2/5):
+
+  Discussion: {AI12-0412-1} As this Reference Manual was frozen, a
+  significant incompatibility has come to light with the above rule. The
+  wording makes calls to non-abstract primitives of a tagged abstract
+  type illegal even if no abstract routines are involved in the
+  Pre'Class or Post'Class. It is likely that the above rule will be
+  adjusted; check with ARG work at www.ada_auth.org/arg.html to find the
+  adjusted rules. 
 
 !ACATS test
 
+ACATS B-Tests should be adjusted to not include cases allowed by this change.
+There might be value to having an ACATS C-Test to ensuring that an example
+like the one in the question is legal and executes properly.
 
 !appendix
 

Questions? Ask the ACAA Technical Agent