!standard 7.5(8.1/3) 13-05-09 AC95-00246/00 !standard 7.5(8.2/3) !standard 7.5(8.3/3) !standard 7.5(8.4/3) !standard 7.5(8.5/3) !standard 7.5(8.6/3) !class confirmation 13-05-09 !status received no action 13-05-09 !status received 13-02-07 !subject Types with immutably limited components !summary !appendix From: Gary Dismukes Sent: Thursday, February 7, 2013 4:53 PM In compiling the ACATS tests for Ada 2012, AdaCore found a B test concerning legality of 'Access (B3A0001) where we don't currently flag an ERROR line that involves applying the attribute to a current instance. It's a case where the record type has an immutably limited component, but the type itself is not explicitly declared as limited. By the rules for immutably limited (in 7.5(8.1/3-8.6/3), a type that has an immutably limited component (or more properly, part) is not immutably limited simply due to having such a component/part, so in the test, current_instance'Access is not legal. Question: Should we (re)consider making such types immutably limited? [BTW, Steve says that he had recently noticed this in some other context, and he and Randy discussed it a little, with both having the feeling that types with immutably limited parts should be immutably limited.] Since at least one compiler (GNAT) treats such types as immutably limited, that would be a point in favor of a rule change (avoiding possible incompatibilities for existing code). Note that there would also be some language-use benefit to making this change, in that it would allow some cases that are currently illegal: 1) Such types could have access discriminants with defaults. 2) The 'aliased' keyword would be allowed for return objects of such types in an extended return statement. 3) 'Access would be applicable to current instances of such types. (Admittedly, allowing those cases would not bring a large benefit.) One question is whether there's a good reason for not making such types immutably limited. Based on discussion in the !appendix section of AI05-0052 ("Coextensions and Distributed Overhead", which is where the definition of immutably limited comes from), it seems clear that excluding such types was intentional. For reference, here's a quote of remarks from Pascal and Tuck pertinent to this: > Pascal Leroy: > > This doesn't address my point that AI 52+63 makes some constructs > legal in TC2 that were illegal in Ada 2005. There is no indication in > any document that I have read that says that it was intended. In > particular, I draw your attention to 3.7(10.e/2) which makes it very > clear that the designers of Ada 95, in their infinite wisdom, decided > that a type with an immutably limited component was not itself > immutably limited (and I think they were right then, and wrong now). > > Tucker Taft: > > Sorry, I hadn't understood your point. Now I see and I agree there is > no need to give special "immutably limited" status to types that get > limitedness from their subcomponents. > > So we could eliminate the fourth bullet. [Note: The "fourth bullet" refers to the following, which was being considered at one point for inclusion in the definition of immutably limited: * A type with a part that is of an immutably limited type. ] The paragraph mentioned by Pascal is the second AARM paragraph in a list of alternative rules considered for types that have access discriminants. The rationale against the 10.e/2 alternative seems to have mainly to do with readability (and maybe error-proneness). For ease of reference, here are 3.7(10.c/2-10.e/2): 10.c/2 Reason: {AI95-00230-01} We also considered the following rules for access discriminants: 10.d If a type has an access discriminant, this automatically makes it limited, just like having a limited component automatically makes a type limited. This was rejected because it decreases program readability, and because it seemed error prone (two bugs in a previous version of the RM9X were attributable to this rule). 10.e/2 A type with an access discriminant shall be limited. This is equivalent to the rule we actually chose for Ada 95, except that it allows a type to have an access discriminant if it is limited just because of a limited component. For example, any record containing a task would be allowed to have an access discriminant, whereas the actual rule requires limited record. This rule was also rejected due to readability concerns, and because would interact badly with the rules for limited types that become nonlimited. The 10.e/2 paragraph also says it would "interact badly with the rules for limited types that become nonlimited", but note that these paragraphs were originally written for Ada 95 (the only change from 10.e to 10.e/2 was the addition of "for Ada 95"), and that latter rationale about "limited types that become nonlimited" doesn't seem relevant for immutably limited types. *************************************************************** From: Robert Dewar Sent: Thursday, February 7, 2013 5:00 PM > Since at least one compiler (GNAT) treats such types as immutably > limited, or you could have said Since all existing Ada 2012 compilers treat such types as immutably limited, :-) > that would be a point in favor of a rule change (avoiding possible > incompatibilities for existing code). Note that there would also be > some language-use benefit to making this change There is definitely an advantage to making this change, I am strongly in favor on this basis. *************************************************************** From: Steve Baird Sent: Thursday, February 7, 2013 5:59 PM > [BTW, Steve says that he had recently noticed this in some other > context, and he and Randy discussed it a little, with both having the > feeling that types with immutably limited parts should be immutably > limited.] More precisely, neither of us could see any reason why they shouldn't be (I didn't mean to misstate Randy's position). *************************************************************** From: Randy Brukardt Sent: Thursday, February 7, 2013 6:13 PM > > Since at least one compiler (GNAT) treats such types as immutably > > limited, > > or you could have said > > Since all existing Ada 2012 compilers treat such types as immutably > limited, > > :-) But that's not relevant, because the concept of "immutably limited" types goes back to Ada 95 and the rules that Gary was quoting the notes from. The main difference with Ada 2012 is that we gave it a name, because we found that the language was repeatedly saying "a task or protected type or a type that is a descendant of an explicitly limited record type". Besides, the case Gary mentioned is only one of several uses of "immutably limited" in the language. Does GNAT allow too much in *all* of these cases, or just this one? (I'd be surprised if an access discriminant with a default expression was allowed for a type with an immutably limited part, as this would be a change from Ada 2005 when no semantic change was made (or intended). And, of course, the ACATS test Gary was commenting on is an Ada 2005 test. Ada 2012 did not intend to change the semantics of 3.10(9/3), just the wording (that's how it's documented in the AARM). What does GNAT do on such examples in Ada 2005 mode? In particular, does it pass the test in Ada 2005 mode? If so, there's hardly any reason to assume that anyone is depending on GNAT's bug in Ada 2012 mode. > > that would be a point in favor of a rule change (avoiding possible > > incompatibilities for existing code). Note that there would also be > > some language-use benefit to making this change > > There is definitely an advantage to making this change, I am strongly > in favor on this basis. I worry that this isn't as straightforward as it looks. Currently, whether a type is immutably limited is clear from its declaration: it explicitly has the word limited, or task, or protected, or synchronized somewhere in the declaration (or it is derived from such a type) [or it is a partial view with defaulted access discriminant - please ignore that!]. This is a property that depends solely on the declaration that you can see. But a private view of an immutably limited type might not be immutably limited (in order to preserve privacy). That means that whether a component of a type T is immutably limited could depend on the visibility that the type T has on the type of the component. That way be dragons!! Probably, we'd want the rule to be that the type is immutably limited if it has any parts that are immutably limited *at the point of the declaration*. But of course that could have surprising results. And remember that we now allow adding the keyword "limited" to record types, and that makes it immutably limited. If we were designing Ada from scratch knowing what we know now, we would have required that keyword on all limited types (it improves readability and eliminates some anomalies that currently exist, such as a limited type becoming non-limited somewhere later in its scope). So why would we want to expand those anomalies?? Let users put "limited" on their types that use a current instance in this way. So I'm against expanding this, especially when we originally considered doing this in the context of Ada 2005, and rejected it. Ada 2005 adopted this tighter rule because the relaxed rule leads to madness (see AI95-00225-1 for details). AI95-00225-1 was a Binding Interpretation on Ada 95, and it explicitly noted that it might break code that depends on looser semantics. But it also noted that Ada 95 compilers implemented this rule differently, so there was no hope of portability of code that didn't follow the tighter rule. *************************************************************** From: Randy Brukardt Sent: Thursday, February 7, 2013 6:18 PM > More precisely, neither of us could see any reason why they shouldn't > be (I didn't mean to misstate Randy's position). But Gary's post reminded me why it should not be. See my reply to Robert. In the AI95-00225-1 that I referred, Tucker said: This all seems pretty unsavory, and makes me want to suggest that the rule should be that you may only use T'[Unchecked_]Access inside an untagged record type if it explicitly uses the word "limited" in its definition. This has the nice characteristic that only types that are return-by-reference have an aliased current instance. That's good, because if they are not return-by-reference, (and not controlled), then the object is allowed to be copied and moved around as part of a function return, which would render the use of T'[Unchecked_]Access pretty meaningless. Essentially everyone agreed with this position; that's since been expanded to the idea of "immutably limited", but the basic concept is the same. I don't think we want to make any change here, unless we want to reintroduce the madness that Tucker described in his original e-mail (the first one in the !appendix of AI95-00225-1, read it here: http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ais/ai-00225.txt?rev=1.7). *************************************************************** From: Tucker Taft Sent: Thursday, February 7, 2013 7:01 PM I clearly remember having this discussion about "immutably limited" and coming to the conclusion that allowing components to make an enclosing type "immutably limited" added complexity to the rules. The basic problem is that an untagged limited private type could become non-limited in the full view, or could become immutably limited, in the full view. If a type has a component that is of a limited private type, we would need rules that talk about what happens if and when it becomes immutably limited and it is used as a component. We know those rules are painful when talking about becoming non-limited and the effects on containing types, it seemed unnecessary to do the same thing for immutably limited. I also resist the temptation to enshrine a GNAT bug as a new language rule, just because it is the first Ada 2005 or first Ada 2012 compiler. We had a rationale for the current rule, and I don't see a compelling argument for reversing this decision. *************************************************************** From: Randy Brukardt Sent: Thursday, February 7, 2013 7:24 PM Thanks, Tuck. The decision was compelling enough that we created an Ada 2005 ACATS test (back in 2007) to check that the correct rule was enforced. I have to presume that GNAT does the correct thing for Ada 2005, I can't imagine that you've been ignoring a failing test for more than 5 years without either bringing it up to the ACAA and/or ARG or fixing it. And no semantic change was intended by the introduction of the "immutably limited" term (particularly in this case, which does not apply to private types; I think the private cases were new in Ada 2012). So what we have here is a compiler that made a mistake somewhere and changed its checking when no change was needed or intended. Moreover, this is a pretty obscure case and the fix for any user running into it is to add "limited" to the record type; it doesn't make sense to tie the language into knots to support a broken compiler when the fix is that easy (I refuse to call it a "workaround", as the intent has been for years that "limited" ought to be given in such cases; failing to do so is a user error compounded by a compiler that failed to complain). *************************************************************** From: Steve Baird Sent: Thursday, February 7, 2013 7:32 PM > The basic problem is that an untagged limited private type could > become non-limited in the full view, or could become immutably > limited, in the full view. If a type has a component that is of a > limited private type, we would need rules that talk about what happens > if and when it becomes immutably limited and it is used as a > component. We know those rules are painful when talking about > becoming non-limited and the effects on containing types, it seemed > unnecessary to do the same thing for immutably limited. I had forgotten this, but it is coming back to me now and I think you are right (contrary to my earlier opinion). Do we really want "immutably limited" to be defined via the "characteristics" rules of 7.3.1(4/1) so that in this example package Pkg is type T is limited private; package Nested is type Lp is limited private; private type Lp is array (1 ..3) of Some_Task_Type; end; ... private type T is record Component : Nested.Lp; end record; end; the type T is inherently limited only inside the body of Nested? Probably not. Do we want the replacement of a visible task type with a limited private (untagged) type implemented as a task type to break Current_Instance'Access uses of types which have this type as a subcomponent type (because the current instance might no longer be aliased). Again, probably not. To be sure, this does nothing to help in the situation where someone wants to put "aliased" on an extended return statement for a function returning an array type whose element type is immutably limited. The normal solution when one wants a type to be immutably limited is to explicitly declare it as such. Unfortunately, there is no way to do that for an array type. Fortunately, this seems like an unimportant corner case. *************************************************************** From: Gary Dismukes Sent: Thursday, February 7, 2013 8:10 PM > Thanks, Tuck. The decision was compelling enough that we created an > Ada 2005 ACATS test (back in 2007) to check that the correct rule was > enforced. I have to presume that GNAT does the correct thing for Ada > 2005, I can't imagine that you've been ignoring a failing test for > more than 5 years without either bringing it up to the ACAA and/or ARG > or fixing it. And no semantic change was intended by the introduction of the > "immutably limited" term (particularly in this case, which does not apply > to private types; I think the private cases were new in Ada 2012). So what we > have here is a compiler that made a mistake somewhere and changed its > checking when no change was needed or intended. Moreover, this is a > pretty obscure case and the fix for any user running into it is to add > "limited" to the record type; it doesn't make sense to tie the > language into knots to support a broken compiler when the fix is that > easy (I refuse to call it a "workaround", as the intent has been for > years that "limited" ought to be given in such cases; failing to do so > is a user error compounded by a compiler that failed to complain). I agree with Tuck's and your conclusions, and you're right that GNAT checks this correctly for Ada 2005. For some reason the processing is done differently in the two cases, so that needs to be sorted out. I think that the checking of components is needed by GNAT in some dynamic semantics contexts, but that needs to be separated from the static semantic checking implied by immutably limited. *************************************************************** From: Robert Dewar Sent: Friday, February 8, 2013 4:41 AM > Thanks, Tuck. The decision was compelling enough that we created an > Ada 2005 ACATS test (back in 2007) to check that the correct rule was > enforced. I have to presume that GNAT does the correct thing for Ada > 2005, I can't imagine that you've been ignoring a failing test for > more than 5 years without either bringing it up to the ACAA and/or ARG > or fixing it. And no semantic change was intended by the introduction of the > "immutably limited" term (particularly in this case, which does not apply > to private types; I think the private cases were new in Ada 2012). So what we > have here is a compiler that made a mistake somewhere and changed its > checking when no change was needed or intended. Moreover, this is a > pretty obscure case and the fix for any user running into it is to add > "limited" to the record type; it doesn't make sense to tie the > language into knots to support a broken compiler when the fix is that > easy (I refuse to call it a "workaround", as the intent has been for > years that "limited" ought to be given in such cases; failing to do so > is a user error compounded by a compiler that failed to complain). I am convinced by Tuck and Randy's arguments, I don't think we should make this change after all. My support for the change was based on perceiving it as a useful language addition (not the issue of GNAT comatibility, which is easily fixed either way). Now it does not seem like such a nice or clean addition. ***************************************************************