CVS difference for ais/ai-00229.txt

Differences between 1.4 and version 1.5
Log of other versions for file ais/ai-00229.txt

--- ais/ai-00229.txt	2001/05/26 02:55:11	1.4
+++ ais/ai-00229.txt	2001/06/02 04:13:15	1.5
@@ -363,3 +363,265 @@
 of??
 
 *************************************************************
+
+From: Gray, Michael
+Sent: Tuesday, May 29, 2001 4:27 AM
+
+
+> Yes. It was expected that some existing code would be made illegal; that's
+> the cost of eliminating dangling references. The work-around is the same one
+> recommended for
+
+... I think you missed some text out here.
+
+
+How about the following. I had to modify the structure of the original
+example 'cos child packages have to be library-level; but it's the same
+basic principle.
+
+I think I was incorrect to say that the new rule needs to be extended to
+cover the case of P'Access in the /spec/ of a child unit, because I think
+that is already illegal by 3.10.2 (32). But the case of P'Access in a child
+unit /body/ does need to be caught by the new rule.
+
+
+----------------------------------
+
+package Global is
+  type Ref is access procedure;
+  P, Q : Ref;
+end Global;
+
+generic
+package G is
+  procedure Foo;
+end G;
+
+with Global;
+package body G is
+  X : Natural := 0;
+
+  procedure Foo is
+  begin
+     X := X + 1;
+  end Foo;
+begin
+  Global.P := Foo'Access; -- the new rule makes this illegal.
+end G;
+
+generic
+package G.C is
+  procedure Dummy; -- just to make body non-optional
+end;
+
+with Global;
+package body G.C is
+  procedure Dummy is begin null; end;
+begin
+  Global.Q := Foo'Access; -- but the new rule does not make this illegal.
+end G.C;
+
+with G.C;
+with Global;
+procedure Dangle is
+
+  procedure Bar is
+    package I is new G; -- Store a reference to I.Foo in Global.P.
+    package J is new I.C; -- and store another one in Global.Q.
+  begin
+    null;
+  end Bar;
+
+begin
+  Bar;
+  Global.P.all; -- Oops, I.X is gone?
+  Global.Q.all; -- ditto
+end Dangle;
+
+*************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, May 31, 2001 9:13 PM
+
+> > Yes. It was expected that some existing code would be made illegal; that's
+> > the cost of eliminating dangling references. The work-around is the same one
+> > recommended for
+>
+> ... I think you missed some text out here.
+
+I went to look up a reference, got side-tracked, and never finished the
+thought. But it was something to the effect that the work-around is the
+standard one for avoiding accessibility checks in generics. (I suspect that
+the example I cannot find was deleted from AARM when object types were given
+run-time accessibility checks - that was relatively late in the design of
+Ada 95.)
+
+> How about the following. I had to modify the structure of the original
+> example 'cos child packages have to be library-level; but it's the same
+> basic principle.
+
+I think you are correct. Created a slightly modified version of your program
+(I just added some Text_IO calls so we can see what's going on).
+
+I compiled it on GNAT 3.14a for grins, and it compiles successfully, and
+when I run it, I get:
+
+-- B3A200X - Create dangling references (AI-229)
+** B3A200X_G.Foo called!
+
+raised PROGRAM_ERROR : unhandled signal
+
+I then tried ObjectAda 7.2, which also compiles successfully, and when I run
+it, I get:
+
+-- B3A200X - Create dangling references (AI-229)
+Program terminated by an exception propagated out of the main subprogram.
+Exception raised : Constraint_Error
+Exception message : access error
+Executable name:   C:\PROGRAM
+FILES\AONIX\OBJECTADA\W\W-WIN32(INTEL)-DEBUG\B3A20
+0X.EXE
+
+Line      Subprogram name                 File
+--------  ------------------------------  ------------
+      18  b3a200x.bar.i.foo               b3a200x.a
+      52  b3a200x                         b3a200x.a
+     300  _rtsadamain                     m:\adamagic\src\rts_nt\init.c
+
+End of propagation.
+Program aborted.
+
+Obviously, this is a real problem! (If someone would like the program, just
+ask me.)
+
+*************************************************************
+
+From: Gray, Michael
+Sent: Thursday, May 31, 2001 6:25 AM
+
+> But the case of P'Access in a child unit /body/ does
+> need to be caught by the new rule.
+>
+
+and so does the case of P'Access in the body of a generic that takes an
+instantiation of G (the package which declares P) as a formal package
+parameter.
+
+... which makes me think that some systematic analysis is required to
+identify /all/ the cases in which dangling references to subprograms could
+arise.
+
+
+*************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, May 31, 2001 9:43 PM
+
+> > But the case of P'Access in a child unit /body/ does
+> > need to be caught by the new rule.
+> >
+>
+> and so does the case of P'Access in the body of a generic that takes an
+> instantiation of G (the package which declares P) as a formal package
+> parameter.
+
+Ugh.
+
+> ... which makes me think that some systematic analysis is required to
+> identify /all/ the cases in which dangling references to subprograms could
+> arise.
+
+Sounds like you're doing a good job; keep it up! :-)
+
+Seriously, I'm not sure how anyone could go about a systematic analysis.
+These are a bunch of rather weird cases. Keep in mind that a child of a
+generic is just syntactic sugar for an implicit generic package parameter
+(at least that is how it was sold to the DRs). So it's no surprising that
+both have the same problem.
+
+I modified my test program to include a formal package case, with
+essentially the same results as the previous version of the program. (That
+is, none of the compilers detected an error, and failed at runtime in
+various ways.)
+
+It seems to me that the existing rules cover all of the cases except those
+in generic bodies. Thus, we simply have to prohibit problems in generic
+bodies. Probably the best way is simply to outlaw them. I think a rule
+trying to define exactly which generic bodies cannot take 'Access probably
+would simply leave more holes for future patching.
+
+So, I suggest fixing the rule as follows:
+
+"If the subprogram denoted by P is declared within a generic specification,
+and the ultimate ancestor of S is not declared within the generic unit, then
+the expression P'Access shall not occur in any generic body."
+
+(Spelling out the places that are illegal would have to say:
+"If the subprogram denoted by P is declared within a generic specification,
+and the ultimate ancestor of S is not declared within the generic unit, then
+the expression P'Access shall not occur in the generic body, the body of any
+child of the generic unit, or in the body of any generic which has a formal
+parameter of the generic unit."
+Quite a mouthful!)
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Friday, June 1, 2000 9:19 AM
+
+> and so does the case of P'Access in the body of a generic that takes an
+> instantiation of G (the package which declares P) as a formal package
+> parameter.
+
+True.  In fact, you don't even need a formal package to do the trick, a formal
+subprogram is enough.
+
+I believe that the wording "generic specification" is lousy.  It should say "the
+visible or private part of a generic".  Because the formal part is part of the
+visible part, the problem you mention should be covered.  Also, it deals nicely
+with the case of a generic subprogram, a situation which I overlooked when I did
+the initial write-up.
+
+Regarding the issue with children of generics, I believe it would be sufficient
+to talk of "the body of any descendant" of the generic in question.
+
+So I guess I am proposing the following wording:
+
+"If the subprogram denoted by P is declared within the visible or private part
+of a generic, and the expression P'Access occurs within the body of a descendant
+of that generic, then the ultimate ancestor of S shall be declared within the
+generic unit."
+
+Comments anyone?
+
+*************************************************************
+
+From: Randy Brukardt
+Sent: Friday, June 1, 2001 7:10 PM
+
+This looks better than my attempt.
+
+However, we now have two very similar rules, which I think we can merge. For
+reference, the existing rule is:
+
+"If a subprogram denoted by P is declared within a generic body, S shall be
+declared within the generic body."
+
+The predicate can easily be merged. Since there is no outside visibility into a
+body, the part about P'Access occuring in the body is redundant.
+
+The interesting question is whether there is any need to restrict S to the
+generic body for subprograms declared in the body. I don't think there is for
+generic sharing purposes (if there is a reason, it would also apply to the new
+rule), and there can't be any accessibility problems. So I think it is OK to
+allow S to be declared anywhere in the generic. Thus, we get the following
+(which replaces the existing rule):
+
+"If the subprogram denoted by P is declared within a generic, and the expression
+P'Access occurs within the body of a descendant of that generic, then the
+ultimate ancestor of S shall be declared within the generic unit."
+
+A nice simple rule. It even allows a few cases currently rejected. Does anyone
+have an objection to this rule??
+
+*************************************************************

Questions? Ask the ACAA Technical Agent