!standard 13.1.1(38/3) 20-09-09 AI12-0389-1/02 !standard 13.12.1(6.3/3) !class Amendment 20-08-31 !status Amendment 1-2012 20-09-09 !status WG9 Approved 22-06-22 !status ARG Approved 12-1-1 20-09-09 !status work item 20-08-31 !status received 20-07-23 !priority Low !difficulty Easy !subject Ignoring unrecognized aspects !summary Implementations are granted permission to ignore specifications of unrecognized aspects. Two new restrictions, No_Unrecognized_Aspects and No_Unrecognized_Pragmas, are defined. !problem Ada allows an implementation the freedom to ignore an unrecognized pragma (see ARM 2.8(15)), but does not grant such a freedom in the case of a specification of an unrecognized aspect (see AARM 13.1.1(38.a/3)). It would be useful to allow such freedom for aspect specifications for much the same reasons that it is useful for pragmas. !proposal (See Summary.) !wording Add after 13.1.1(38/3) (in the Implementation Permissions section) An implementation may ignore the specification of an unrecognized aspect; if an implementation chooses to ignore such an aspect specification (as opposed to rejecting it), then it has no effect on the semantics of the program except for possibly (and this is not required) the rejection of syntax errors within the aspect_definition. AARM note: Identifying the textual end of an aspect_definition for an unrecognized aspect may be challenging, particularly if the syntax for the unrecognized aspect's aspect_definition is implementation-defined. It is not specified how an implementation might accomplish this. Note that an implementation is never *required* to be able to do this; if an aspect_definition for an unrecognized aspect is problematic in any way, then it can always be rejected (as opposed to being ignored). Delete from AARM 13.1.1(38.a/3) Unrecognized aspects are illegal whether or not they use custom syntax, so this freedom does not reduce portability. Replace AARM 13.14(19.k) 2.8 overrides the freezing rules in the case of unrecognized pragmas. with 2.8 overrides the freezing rules in the case of an unrecognized pragma; similarly 13.1.1 overrides the freezing rules in the case of a specification of an unrecognized aspect. Append after 13.12.1(6.3/3) (as part of the list of restriction identifiers) No_Unrecognized_Aspects There are no aspect_specifications having an unrecognized aspect_identifier. This restriction applies only to the current compilation or environment, not the entire partition. AARM Ramification: When this restriction is in effect, unrecognized aspects cannot be ignored in the current compilation; they violate the restriction. This is true despite the Implementation Permission of 13.1.1. No_Unrecognized_Pragmas There are no pragmas having an unrecognized pragma identifier. This restriction applies only to the current compilation or environment, not the entire partition. AARM Ramification: When this restriction is in effect, unrecognized pragmas cannot be ignored in the current compilation; they violate the restriction. This is true despite the rules of 2.8. !discussion (See problem.) !corrigendum 13.1.1(38/3) @dinsa Implementations may support implementation-defined aspects. The @fa for an implementation-defined aspect may use an implementation-defined syntax for the @fa, and may follow implementation-defined legality and semantics rules. @dinst An implementation may ignore the specification of an unrecognized aspect; if an implementation chooses to ignore such an aspect specification (as opposed to rejecting it), then it has no effect on the semantics of the program except for possibly (and this is not required) the rejection of syntax errors within the @fa. !corrigendum 13.12.1(6.3/3) @dinsa @xhang<@xterm Identifies a @fa which is not to be used.> @dinss @xhang<@xterm There are no @fas having an unrecognized @i@fa. This restriction applies only to the current compilation or environment, not the entire partition.> @xhang<@xterm There are no @fas having an unrecognized pragma @fa. This restriction applies only to the current compilation or environment, not the entire partition.> !ASIS No ASIS effect. !ACATS test The ACATS does not test implementation choices, so no tests are needed for the new rule. However, it might be necessary to modify an existing test that expects the rejection of an unknown aspect. !appendix From: Steve Baird Sent: Thursday, July 23, 2020 7:18 PM Ada allows an implementation the freedom to ignore an unrecognized pragma (see ARM 2.8(15)), but does not grant such a freedom in the case of a specification of an unrecognized aspect (see AARM 13.1.1(38.a/3)). It would be useful to relax that restriction in order to make it easier for older versions of tools (including, but not limited to, compilers) to be able to process newer Ada source code that includes specifications of recently-added aspects (language-defined or not). Aspect specifications are somewhat different than pragmas because implementation-defined aspect_definition syntax is permitted (see 13.1.1(38/3)). But as with any implementation permission, no new requirements are imposed. For example, one implementation might choose to ignore this new permission completely while another might choose to take advantage of it only in the case of an aspect_definition which has "standard" syntax. There is a related issue having to do with the treatment of syntactically incorrect ignored pragmas (see ARM 2.8(15)); presumably definitions of unrecognized aspects could be handled similarly. Interactions with freezing rules would also presumably follow the existing model for unrecognized pragmas (see AARM 13.14(19.k)). One might be concerned about spelling errors. It would be undesirable to quietly ignore the aspect definition in procedure Foo with In_Line; A first response to this point is that typically a warning would be generated in a situation like this, even if warning generation is not part of the language definition. A second is that this is nothing new; we already have the same situation with misspelled pragma names, as in pragma In_Line (Foo); One might argue that there is no need for a change here because implementations are already allowed, in effect at least, to ignore unrecognized aspects. Given the specification of an unrecognized aspect, an implementation could claim that in fact the aspect is recognized as an implementation-defined pragma which is defined to have no effect. That does not seem like the right solution to this problem (the documentation requirement associated with M.2(44.1/3) could be finessed, but really?), and it seems unnecessarily inconsistent with the treatment of pragmas. I'm not proposing specific wording here; just broaching the subject. **************************************************************** From: Tucker Taft Sent: Thursday, July 23, 2020 8:01 PM I support the idea. Aspects have begun to replace pragmas in many contexts, and should have the same nice property of not interfering with the ability of the code to compile with compilers or on targets where the aspect is not defined or not meaningful. This also argues for a "good taste in implementation-defined aspects" philosophy that we somewhat attempted to define for pragmas. Namely, an implementation-defined aspect should typically not make an illegal program legal, but should rather only affect performance, or impose additional restrictions that make a legal program illegal. This is not something we would ever try to enforce, and clearly would defeat the purpose of aspects that are designed to enable some "syntactic sugar" for a particular type. But it seems something to keep in mind when an implementation defines its own aspect. The goal is that a program using an implementation-defined aspect typically remains legal if the aspect is simply ignored, so it can be compiled by an older or different compiler. This is also quite consistent with the "generalized aspects" AI (AI12-0355-1), where an aspect can be associated with an underlying subsystem, so even the compiler doesn't have to really "understand" the aspect specification to parse it and pass the information content through to an underlying subsystem like OpenMP (or, e.g. CUDA) (http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0355-1.txt). **************************************************************** From: Randy Brukardt Sent: Thursday, July 23, 2020 8:44 PM I'm cool to this idea. I am not a fan of the "ignoring unrecognized pragmas" rule in the first place. When we were working on Claw, we had a number of instances where someone used the wrong version of an implementation-specific unit. Those units spewed warnings rather than errors (because of the pragma rule), warnings typically don't stop compilations, so usually those would just scroll by when doing a build. When the resulting program didn't work, one wasted a lot of time tracking down a problem which was just a configuration error. We also had cases where impl-def pragmas were misspelled or misapplied and again the problem was hard to find. Aspects (which are always entity-specific) are much more likely to involve a property that is critical to the operation of the program, so they are even less likely to be a good idea to be ignored. One of the reasons that I prefer aspects to pragmas is that they don't involve the ignoring nonsense. Tucker mentioned the need for "good taste in implementation-defined aspects". Please, no. Most of the impl-def aspects that I've defined to date wouldn't meet any such requirements. And I don't think it is reasonable to hamstring implementers that way in working out mechanisms to properly check Global use for access types and other important issues that will not be solved in Ada 202x. I recall that Robert Dewar was very against the idea of "good taste in impl-def pragmas", and I believe he would have felt the same about doing the same for aspects. Without some form of "good taste", ignoring aspects is downright dangerous. If someone is worried about portability, then don't use impl-def aspects. That doesn't seem that hard to understand. As Steve points out, ignoring an aspect can be done if the implementation recognizes it and treats it as implementation-defined. That seems to me to be the right answer, since it is only safe to ignore aspects that you *know* will not cause problems if ignored. (For instance, Janus/Ada will soon ignore Pre/Post if the Assertion_Mode is Ignore, in order to allow using those in code even before they get implemented in the compiler. That's pretty safe, since they wouldn't be executed anyway, and the only thing that might be missed is an illegal precondition expression. But I wouldn't want to do anything like that for No_Return.) **************************************************************** From: Tucker Taft Sent: Thursday, July 23, 2020 9:21 PM Implementations can of course have different modes of behavior with respect to implementation-defined or simply unrecognized aspects. So the question what "mode" or "modes" should all compilers support? There is already a restriction No_Implementation_Aspect_Specifications, so either that restriction, or another one we could invent for this purpose, could be used to provide the protection you want. In my view, the "Restriction" mechanism is kind of the best of both worlds, in that it permits a project that wants to avoid certain problems to self-impose an appropriate restriction at the library level, while those projects that appreciate a less strict mode can choose not to impose such a restriction. I think having various standard restrictions is better than inventing a different set of command-line parameters for every compiler to control its various modes. So perhaps we should add a pair of standard restrictions for No_Unrecognized_Pragmas and No_Unrecognized_Aspect_Specifications to go along with loosening the basic rule for aspects to match that of pragmas. **************************************************************** From: Richard Wai Sent: Thursday, July 23, 2020 10:54 PM I think doing this is obviously orthagonal with pragmas, and you probably all know by now how much of a fan I am of orthagonality. I definitely ran into this problem with some tooling we built that makes use of such unrecognized pragmas, where those pragmas are clearly more naturally suited to aspects, but that was not an option. It appears arbirary. I think it is important to mention that “implementation-defined aspect should typically not make an illegal program legal, but should rather only affect performance, or impose additional restrictions that make a legal program illegal." Afterall, it is not as if we are talking about user-defined aspects here (as close as AI12-0351-1 may be to that), anyone doing this is making some kind of compiler, tooling, or runtime support library, so implementation advice at the least seems rational. **************************************************************** From: Jean-Pierre Rosen Sent: Friday, July 24, 2020 1:31 AM There is a minimum good taste which is necessary, typically: "implementation-defined aspect should typically not make an illegal program legal" Typically, we don't want: type Void is null record; type Universal_Pointer is access Void with C_Can_Point_To_Anything; **************************************************************** From: Arnaud Charlet Sent: Friday, July 24, 2020 1:57 AM I'm also strongly in favor of this, users can always enable warning-as-error and compilers can provide a "picky pedantic" mode where unknown aspects are illegal, but in our experience with GNAT, having this capability is very important since otherwise it e.g. prevents older versions of GNAT (compiler or ASIS based tools) to be able to process newer Ada or SPARK source code. The example of SPARK specific aspects is a typical case, but some Ada 202x aspects also are in this category or desirable to ignore at least in some cases. This also makes it easier for tool developers to experiment with new aspects and still be able to compile their code, which is something we want to encourage for the Ada ecosystem. pragmas have always provided this capability (as in other languages), and given that we are deprecating most pragmas in favor of aspects these days, providing the ability for people to experiment with new aspects is really important IMO. > There is a minimum good taste which is necessary, typically: > "implementation-defined aspect should typically not make an illegal > program legal" Right, the same is already true for pragmas. **************************************************************** From: Bob Duff Sent: Friday, July 24, 2020 10:08 AM > I'm also strongly in favor of this,... I basically agree with Arno. But this whole argument is based on a delusion held by language designers -- we tend to (wrongly) think we can boss people around. ;-) In fact, language definitions don't require anybody to do anything. They just define the language. AdaCore is going to do what it decides is best regarding ignoring aspects (and everything else). The only possible effect on AdaCore of an unfavorable ruling by ARG would be that AdaCore might have a switch so they can honestly say GNAT (has a mode in which it) conforms to the RM. Likewise for other compiler writers. I strongly object to spending even one nanosecond arguing about what aspects are "in good taste". The job of the RM is to define Ada, not to give advice to compiler writers about taste in language extensions. And if you want to turn that advice into requirements, then see above about "delusion". Restrictions is one of my favorite features, but I don't think Tucker's suggested new restrictions are worth the trouble. I don't strongly object to them, though. As to the "warnings scroll off the screen" problem, that's a general problem about warnings (more precisely, diagnostic messages that don't kill the build), so a solution specific to aspect-related warnings is inappropriate. Anyway, it's an easy problem to solve, and is already solved in GNAT and probably other Ada compilers. **************************************************************** From: Randy Brukardt Sent: Saturday, July 25, 2020 7:15 PM ... > I strongly object to spending even one nanosecond arguing about what > aspects are "in good taste". The job of the RM is to define Ada, not to > give advice to compiler writers about taste in language extensions. And > if you want to turn that advice into requirements, then see above about > "delusion". Yup. If someone wants to define an aspect No_Accessibility_Check_Nonsense to be applied to access types, who are we to say that they can't do that? Moreover, the idea that making illegal code legal is somehow more problematic than making legal code illegal seems dubious at best. Richard said something about making Ada more consistent -- but if you're going to do that, you'll also have to allow ignoring unrecognized attribute_definition_clauses. Somehow, that's never been thought to be a good idea during the entire Ada 83 to present timeframe, so I have to wonder why it is suddenly a good idea for aspects (many of which replace attribute_definition_clauses). Anyway, it won't be more consistent to allow ignoring of aspects, it just moves a bump. I hope no one thinks that ignoring everything unrecognized is a good idea (my understanding is that the major objection to the proposed ghost code idea was the concern that a misspelled ghost name would be ignored). > As to the "warnings scroll off the screen" problem, that's a general > problem about warnings (more precisely, diagnostic messages that don't > kill the build), so a solution specific to aspect-related warnings is > inappropriate. Anyway, it's an easy problem to solve, and is already > solved in GNAT and probably other Ada compilers. Now you're being delusional. GNAT surely does not solve this problem. When I compile my code with GNAT, I get bunches of useless warnings about loops that only execute once and other similar nonsense. These potentially push off useful warnings and also make it much less likely that I will even look carefully at the messages. In such cases, unrecognized pragma warnings are lost. Setting warnings-as-errors does not help, as the useless warnings would prevent the compilation of the programs. One can "solve" the problem by modifying the source code, but then you are making custom versions for every compiler -- if you're doing that anyway, you can trivially get rid of any inappropriate pragmas. Ergo, I don't think ignoring pragmas helps anything (and can be very harmful), and thus I continue to object to expanding it to anything else. **************************************************************** From: Tucker Taft Sent: Saturday, July 25, 2020 9:24 PM Attributes are different in my mind, because any use of an attribute implies you need to know the type of the attribute. So I don't see much value in ignoring unrecognized implementation-defined attributes, since you really can't generate code. And the same will be true for aspect specifications that are specifying the value of an implementation-defined attributes, if the attribute actually gets referenced. But there might very likely be aspects analogous to pragmas, like "Inline_Always" or "Lock_Free" that are useful when understood by a compiler, but not a serious portability problem if ignored when not recognized. My view is that we can help the "pragma" issue and not create a bizarre incentive to define implementation-defined pragmas when an implementation-defined aspect would clearly be preferable, by defining two standard restrictions, No_Unrecognized_Pragma and No_Unrecognized_Aspect_Specifications, thereby providing the checking folks like you prefer for pragmas, and allowing "benign" implementation-defined aspects to be treated like pragmas, to further enable the general move away from pragmas. **************************************************************** From: Steve Baird Sent: Monday, August 31, 2020 5:57 PM Here is an AI for this one, pretty much just writing up what has already been discussed. [This is version /01 of this AI - Editor.] **************************************************************** From: Randy Brukardt Sent: Friday, October 2, 2020 9:52 PM In this AI, we define a restriction as follows: No_Unrecognized_Aspects Any aspect_specification having an unrecognized aspect_identifier shall be rejected[ (as opposed to being ignored)]. This restriction applies only to the current compilation or environment, not the entire partition. Bob has typically complained about the use of "reject" in normative wording. Dunno if he napped through the review of this AI :-), but this is precisely the sort of use that he has complained about in the past. Moreover, this is not the typical form for a restriction, which starts something like "There are no ...". Probably it would be better to use wording something like: There are no aspect_specifications having an unrecognized aspect_identifier; they are not ignored. This restriction applies only to the current compilation or environment, not the entire partition. I'm dubious that the part about not ignoring buys anything (at least normatively), since "no aspect_identifiers" doesn't depend on whether they're ignored. So perhaps drop that and explain in an AARM note that this does not allow ignoring aspects: There are no aspect_specifications having an unrecognized aspect_identifier. This restriction applies only to the current compilation or environment, not the entire partition. Ramification: When this restriction is in effect, unrecognized aspect_identifiers cannot be ignored; the Implementation Permission of 13.1.1 does not apply. I'd make a similar change to No_Unrecognized_Pragmas: No_Unrecognized_Pragmas There are no pragmas having an unrecognized pragma identifier. This restriction applies only to the current compilation or environment, not the entire partition. If no one objects, I can treat these rewordings as my editorial review of this AI. **************************************************************** From: Bob Duff Sent: Saturday, October 3, 2020 6:37 AM > In this AI, we define a restriction as follows: > > No_Unrecognized_Aspects > > Any aspect_specification having an unrecognized aspect_identifier shall be > rejected[ (as opposed to being ignored)]. This restriction applies only to > the current compilation or environment, not the entire partition. > > Bob has typically complained about the use of "reject" in normative wording. > Dunno if he napped through the review of this AI :-), ... Apparently. > Moreover, this is not the typical form for a restriction, which starts > something like "There are no ...". Probably it would be better to use > wording something like: > > There are no aspect_specifications having an unrecognized aspect_identifier; > they are not ignored. This restriction applies only to > the current compilation or environment, not the entire partition. OK. > I'm dubious that the part about not ignoring buys anything (at least > normatively), ... Yeah, that's why it's in square brackets in the original you quoted above. > ...since "no aspect_identifiers" doesn't depend on whether they're > ignored. So perhaps drop that and explain in an AARM note that this > does not allow ignoring aspects: > > There are no aspect_specifications having an unrecognized aspect_identifier. > This restriction applies only to the current compilation or environment, not > the entire partition. > > Ramification: When this restriction is in effect, unrecognized > aspect_identifiers cannot be ignored; the Implementation Permission of > 13.1.1 does not apply. I've no opinion whether the non-normative-but-perhaps-informative part should be moved to the AARM. > I'd make a similar change to No_Unrecognized_Pragmas: > > No_Unrecognized_Pragmas > There are no pragmas having an unrecognized pragma identifier. This restriction > applies only to the current compilation or environment, not the entire partition. > > If no one objects, I can treat these rewordings as my editorial review > of this AI. OK! **************************************************************** From: Tucker Taft Sent: Saturday, October 3, 2020 8:48 AM Works for me. ****************************************************************