CVS difference for ai05s/ai05-0296-1.txt

Differences between 1.1 and version 1.2
Log of other versions for file ai05s/ai05-0296-1.txt

--- ai05s/ai05-0296-1.txt	2012/02/16 03:25:56	1.1
+++ ai05s/ai05-0296-1.txt	2012/03/15 07:20:13	1.2
@@ -1,6 +1,8 @@
-!standard  13.14(10)                             12-02-15    AI05-0296-1/01
+!standard  13.14(10)                             12-03-14    AI05-0296-1/02
+!standard  12.6(8.4/2)
 !class Amendment 12-02-15
 !status Amendment 2012 12-02-15
+!status ARG Approved 7-0-3  12-02-25
 !status work item 12-02-15
 !status received 12-01-12
 !priority Low
@@ -9,10 +11,12 @@
 !summary
 
 The profile of actual subprograms of generic instantiations are not frozen
-if the profile of the formal subprogram contains a formal incomplete type
-of the same generic.
+if the profile of the formal subprogram contains a formal untagged incomplete
+type.
 
-!proposal
+The controlling type of a formal abstract subprogram cannot be incomplete.
+
+!problem
 
 All of the containers packages contain code like the following:
 
@@ -26,6 +30,10 @@
 This is illegal, because 13.14(10.2/3) says that an instantiation freezes
 the profiles of all callable entities that it freezes.
 
+!proposal
+
+(See wording.)
+
 !wording
 
 Modify 13.14(10.2/3):
@@ -33,10 +41,15 @@
 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 incomplete type of the same generic};
+parameter or result of a formal untagged incomplete type};
 if the callable entity is an expression function,
 the expression of the expression function causes freezing.
 
+Modify the last sentence of 12.6(8.4/2):
+
+A formal_abstract_subprogram_declaration shall have excatly one controlling
+type{, and that type shall not be incomplete}.
+
 !discussion
 
 Note that this wording does NOT change the freezing of the actual subprogram
@@ -44,17 +57,51 @@
 profile is changed.
 
 It is OK to pass an unfrozen subprogram to a generic in this case, because
-almost no calls on that subprogram are legal inside the generic (by
-3.10.1(10/3)), and the few that are require all of the incomplete parameters to
-be by-reference (and any other parameters will have to be frozen in order for
-objects of the appropriate type to exist).
-
-[Question: We have some hairy rules to allow generic children in some similar
-cases. (I can't find an example, sorry. It's something about "in the scope of
-the generic specification", I think.) My wording will not work in such a case;
-do we need it to?
+no calls on that subprogram are legal inside the generic (by 3.10.1(10/3)).
+
+Unfortunately, we cannot allow this for formal tagged incomplete types, as
+some calls are allowed. The parameter of the tagged incomplete type would
+not be a problem, as it has to be passed by reference and thus we don't need
+to know the representation of the object. But the representation of other
+parameters may need to be known, and that cannot be guaranteed without freezing
+the profile of the subprogram. (It might be possible to use a more relaxed
+rule, but it is too hard to work out the exact details for a last-minute fix.
+We're rather be conservative.)
+
+For example:
+
+   type Cnt_Type is range ...
+
+   generic
+      type Inc is tagged;
+      with function Is_Valid (O : Inc; Cnt : Cnt_Type) return Boolean;
+   package Gen is
+      procedure Do_It (O : Inc);
+   end Gen;
+
+   package body Gen is
+      procedure Do_It (O : Inc) is
+      begin
+         if Is_Valid (O, 1) then -- Legal, better be frozen.
+            ...
+         end if;
+      end Do_It;
+   end Gen;
+
+Note that it only matters that the formal subprogram has one or more
+formal untagged incomplete parameters. As soon as there is one such
+parameter, the subprogram cannot be called and there is no need to require
+the profile to be frozen. The types of other parameters is irrelevant.
 
-i.e.
+---
+
+We purposely do not talk about whose "formal untagged incomplete type" is
+involved, because we want the rule to apply to any generic that can see the
+formal type. (Such a generic has to be nested or a child; other units cannot
+see the formal type, only the actual.)
+
+For instance:
+
     generic
        type Inc;
     package GParent ....
@@ -64,10 +111,60 @@
     package GParent.Child ....
 
     package P is new GParent (Something);
+
+    package C is new GParent.Child (Bar); -- Do not freeze the profile of Bar.
+
+---
+
+In discussing the tagged cases above, another small hole was noted in the
+language definition. A formal abstract subprogram can be used to make a
+dispatching call, and we do not want to allow a dispatching call on a
+tagged incomplete type. The rules prevent any primitive operation from
+being declared on a type that could be called before it is completed, in order
+to prevent such calls. But a formal abstract subprogram is not primitive, so it
+doesn't trigger those rules.
+
+Thus we add a few words to explicitly make this illegal. For example:
+
+     generic
+         type T is tagged;
+         with procedure Do_It (Obj : in T) is abstract; -- Now illegal.
+     package Gen is
+         procedure Really_Do_It (Obj : in T'Class);
+     end Gen;
 
-    package C is new GParent.Child (Bar); -- Exempt Bar from profile freezing?
-	-- Wording above does not do that.
-]
+     package body Gen is
+        procedure Really_Do_It (Obj : in T'Class) is
+        begin
+           Do_It (Obj); -- Dispatching on tagged incomplete; no way!!
+        end Really_Do_It;
+    end Gen;
+
+
+!corrigendum 12.6(8.4/2)
+
+@drepl
+If a formal parameter of a @fa<formal_abstract_subprogram_declaration> is of a
+specific tagged type @i<T> or of an anonymous access type designating a
+specific tagged type @i<T>, @i<T> is called a @i<controlling type> of the
+@fa<formal_abstract_subprogram_declaration>. Similarly, if the result of a
+@fa<formal_abstract_subprogram_declaration> for a function is of a specific
+tagged type @i<T> or of an anonymous access type designating a specific tagged
+type @i<T>, @i<T> is called a controlling type of the
+@fa<formal_abstract_subprogram_declaration>. A
+@fa<formal_abstract_subprogram_declaration> shall have exactly one controlling
+type.
+@dby
+If a formal parameter of a @fa<formal_abstract_subprogram_declaration> is of a
+specific tagged type @i<T> or of an anonymous access type designating a
+specific tagged type @i<T>, @i<T> is called a @i<controlling type> of the
+@fa<formal_abstract_subprogram_declaration>. Similarly, if the result of a
+@fa<formal_abstract_subprogram_declaration> for a function is of a specific
+tagged type @i<T> or of an anonymous access type designating a specific tagged
+type @i<T>, @i<T> is called a controlling type of the
+@fa<formal_abstract_subprogram_declaration>. A
+@fa<formal_abstract_subprogram_declaration> shall have exactly one controlling
+type, and that type shall not be incomplete.
 
 !corrigendum 13.14(10)
 
@@ -80,7 +177,7 @@
 @xbullet<At the place where a @fa<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 incomplete type of the same generic; if the
+parameter or result of a formal untagged incomplete type; if the
 callable entity is an expression function, the @fa<expression> of the expression
 function causes freezing.>
 
@@ -127,8 +224,8 @@
 
 The occurrence of a generic instantiation causes freezing, except in the
 following cases:
-  o   A name which is a generic actual parameter whose corresponding generic formal parameter is a formal incomplete type (see 12.5.1)
-      does not cause freezing.
+  o   A name which is a generic actual parameter whose corresponding generic formal
+      parameter is a formal incomplete type (see 12.5.1) does not cause freezing.
   o   A subprogram whose profile mentions such a type does not cause freezing.
 
 ****************************************************************
@@ -443,5 +540,151 @@
 
 OK, so there isn't really any problem. So you can all ignore the above.
 Never mind. :-)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, March  1, 2012  9:41 AM
+
+Ed and I have different memories of the decision regarding formal incomplete
+types and freezing.  My memory is that we still allow *tagged* formal incomplete
+types.  But when it comes to formal subprograms that reference the formal
+incomplete type, we suppress freezing of the actual subprogram if it references
+an *untagged* formal incomplete type, but we don't suppress freezing just
+because it references a *tagged* formal incomplete type.
+
+Ed remembers the discussion as concluding that we outlawed tagged formal
+incomplete types completely.
+
+Any other memories out there?
+
+****************************************************************
+
+From: Edmond Schonberg
+Sent: Thursday, March  1, 2012  10:08 AM
+
+The original text of AI05-0296 states:
+
+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 incomplete type of
+the same generic}; if the callable entity is an expression function, the
+expression of the expression function causes freezing.
+
+So the change that Tuck proposes is "a formal incomplete TAGGED type of the same
+generic" ?
+
+****************************************************************
+
+From: Edmond Schonberg
+Sent: Thursday, March  1, 2012  11:20 AM
+
+I guess that should be "UNTAGGED", but then what if the subprogram has one of
+each? Maybe it should say "the profile of the entity is frozen, except for
+formals or result type of an untagged incomplete type of the same generic"
+
+If 3.10.2 is the Heart of Darkness, what is the proper term for 13.14?
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, March  1, 2012  11:26 AM
+
+That's what we decided.
+
+****************************************************************
+
+From: Jeff Cousins
+Sent: Thursday, March  1, 2012  11:39 AM
+
+These few words are what I wrote at the time:
+
+  "Only applies to untagged formal incomplete types."
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, March  1, 2012  12:14 PM
+
+>> So the change that Tuck proposes is "a formal incomplete UNTAGGED type of the same generic" ?
+>
+> I guess that should be "UNTAGGED", but then what if the subprogram has
+> one of each? Maybe it should say "the profile of the entity is frozen,
+> except for formals or result type of an untagged incomplete type of
+> the same generic"
+
+No, I would say either you freeze the actual subprogram or you don't.  There
+seems no need for halfway freezing a subprogram, because you can't call it
+halfway.
+
+> If 3.10.2 is the Heart of Darkness, what is the proper term for 13.14?
+
+Where hell freezes over... ;-)
+
+****************************************************************
+
+From: Edmond Schonberg
+Sent: Thursday, March  1, 2012  12:12 PM
+
+> That's what we decided.
+
+Alas, which "that"?
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Friday, March  2, 2012  12:34 PM
+
+Sorry, I answered that from my phone and had limited time and energy to clarify
+the response. And I didn't realize that you had it backwards...
+
+(1) The word "untagged" is to be added to the wording as given in the AI. As
+    Tucker noted, we can only avoid freezing if there is no possibility that the
+    body will make a call on it.
+
+(2) It's only the presence of "untagged incomplete" that triggers the rule, as
+    that prevents any calls. The types of other parameters don't matter, even if
+    tagged incomplete.
+
+(3) I wonder if we have a tiny hole (near) here; the rules depend on the fact
+    that there cannot be any primitive subprograms of a formal type to prevent
+    any dispatching calls. But the purpose of abstract formal subprograms was to
+    allow dispatching calls on them. Thus:
+
+     generic
+         type T is tagged;
+         with procedure Do_It (Obj : in T) is abstract;
+     package Gen is
+         procedure Really_Do_It (Obj : in T'Class);
+     end Gen;
+
+     package body Gen is
+        procedure Really_Do_It (Obj : in T'Class) is
+        begin
+              Do_It (Obj); -- Dispatching on tagged incomplete; no way!!
+        end Really_Do_It;
+    end Gen;
+
+We don't allow dispaching calls on tagged incomplete (elsewhere) because the
+location/representation of the tag is unknown for the incomplete type. We surely
+don't want to allow that here!
+
+We do that for normal tagged incomplete by banning the declaration of primitive
+operations (3.10.1(9.3/2) and also because most such views aren't used in the
+same scope as their declaration). I suspect we need a legality rule that the
+controlling type of a formal abstract subprogram "shall not be incomplete".
+
+Should I add that to this AI, or did I miss a rule somewhere else that would
+make this call illegal??
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Friday, March  2, 2012  1:41 PM
+
+> Should I add that to this AI, or did I miss a rule somewhere else that
+> would make this call illegal??
+
+You should add it to the AI.
 
 ****************************************************************

Questions? Ask the ACAA Technical Agent