!standard 2.8(6) 08-10-23 AI05-0100-1/02 !standard 2.8(7) !class binding interpretation 08-05-28 !status work item 08-05-28 !status received 06-04-15 !priority Low !difficulty Medium !qualifier Omission !subject Placement of pragmas !summary Pragmas are allowed as the only item in a list if that list is allowed to be empty. !question Is the following legal? task type TT is pragma priority(12); end TT; The wording of 2.8(5-7) make it unclear. Those rules say: Pragmas are only allowed at the following places in a program: * After a semicolon delimiter, but not within a formal_part or discriminant_part. * At any place where the syntax rules allow a construct defined by a syntactic category whose name ends with "declaration", "statement", "clause", or "alternative", or one of the syntactic categories variant or exception_handler; but not in place of such a construct. Also at any place where a compilation_unit would be allowed. The syntax for a task is defined as: task_definition ::= {task_item} [private {task_item}] end [task_identifier] task_item ::= entry_declaration | aspect_clause Since a pragma can't occur at the place of a "task_item", the only way the pragma would be syntactically legal here is if one task_item were present, so that the pragma would occur "at the place of" either the entry_declaration or the aspect_clause; but if one task_item were present, then either an entry_declaration or an aspect_clause would have to be present. The same reasoning applies to this: package Pak1 is pragma Elaborate_Body; end Pak1; which appears to be illegal for the same reason (a pragma can't come at the place of a basic_declarative_item). This is disturbing because it would mean the definition of the package Ada in A.2 is illegal! What is the intent of this wording? (Beats me.) !wording Add to 2.8: AARM NOTE: Language Design Principle In general, if all pragmas are erased from a program, the program should remain both syntactically and semantically legal. There are a few exceptions to this general principle (e.g. pragma Import can eliminate the need for a completion), but the principle remains, and is strictly true at the syntactic level. Certainly any implementation-defined pragmas should obey this principle both syntactically and semantically, so that if the pragmas are simply ignored by some other implementation, the program will remain legal. Revise 2.8(5-7) as follows: Pragmas are only allowed at the following places in a program: * After a semicolon delimiter, but not within a formal_part or discriminant_part. * At any place where the syntax rules allow a construct defined by a syntactic category whose name ends with "declaration", {"item",} "statement", "clause", or "alternative", or one of the syntactic categories variant or exception_handler; but not in place of such a construct {if the construct is required, or is part of a list that is required to have at least one such construct [Redundant:, as in a sequence_of_statements]}. Also at any place where a compilation_unit would be allowed. !discussion We have added an explicit language design principle to establish the general point that if pragmas are erased, the program remains legal both syntactically and semantically. Adding "item" to the list of constructs is perhaps not strictly necessary, since generally "item" expands into one of the already permitted constructs, but it also does not seem to hurt. The phrase "but not in place of such a construct" has always caused a bit of confusion. We have qualified the phrase a bit by making it clear it applies when the construct is required or is part of a list that must have at least one element. Hopefully this will remove some of the mystery. --!corrigendum 2.8(7) !ACATS Test ACATS B-Test should be constructed to ensure that pragmas are not allowed in illegal places. (This is a syntax rule, but since it is given by text rather than semantic rules, and there is little use of pragmas in the ACATS, extra testing is needed.) !appendix !topic Possible hole in definition of where pragmas may occur !reference 2.8(7), 9.1(4), 7.1(3) !from Adam Beneschan 08-04-15 !discussion I think Chris Noonan, on comp.lang.ada, has a point about this code fragment (although I strongly disagree with his conclusion that the sky is falling): task type TT is pragma priority(12); end TT; It appears to me that this might not be legal, the way 2.8(5-7) is written: Pragmas are only allowed at the following places in a program: * After a semicolon delimiter, but not within a formal_part or discriminant_part. * At any place where the syntax rules allow a construct defined by a syntactic category whose name ends with "declaration", "statement", "clause", or "alternative", or one of the syntactic categories variant or exception_handler; but not in place of such a construct. Also at any place where a compilation_unit would be allowed. If task_definition (9.1(4)) were defined as: task_definition ::= {entry_declaration} [private {entry_declaration}] end [task_identifier] then it would be clear that this example is legal, since the pragma is coming at the place of an entry_declaration, and it's not "in place of" an entry_declaration because the syntax does not require there to be any entry_declarations. But the actual definition is task_definition ::= {task_item} [private {task_item}] end [task_identifier] task_item ::= entry_declaration | aspect_clause Since a pragma can't occur at the place of a "task_item", the only way the pragma would be syntactically legal here is if one task_item were present, so that the pragma would occur "at the place of" either the entry_declaration or the aspect_clause; but if one task_item were present, then either an entry_declaration or an aspect_clause would have to be present. A bit more disturbing is that the same reasoning applies to this: package Pak1 is pragma Elaborate_Body; end Pak1; which is, I think, technically illegal for the same reason (a pragma can't come at the place of a basic_declarative_item). This is disturbing because it would mean the definition of the package Ada in A.2 is illegal!! I'm not sure if this really needs a fix or just a "to be honest" in AARM or something. But perhaps a couple more categories need to be added to 2.8(7), e.g. * At any place where the syntax rules allow a construct defined by a syntactic category whose name ends with "declaration", "statement", "clause", or "alternative", or one of the syntactic categories variant, exception_handler, task_item, or basic_declarative_item; but not in place of such a construct. Also at any place where a compilation_unit would be allowed. Or there may be a more generic way to phrase things to allow a in a place where the syntax allows zero or more occurrences of some syntactic category C, where one of the choices for C is one of the syntactic categories listed in 2.8(7), by itself. **************************************************************** From: Robert A. Duff Sent: Tuesday, April 15, 2008 11:59 AM > * At any place where the syntax rules allow a construct defined by > a syntactic category whose name ends with "declaration", > "statement", "clause", or "alternative", or one of the syntactic > categories variant or exception_handler; but not in place of > such a construct. Also at any place where a compilation_unit > would be allowed. I've never been able to make sense of that "but not in place of" wording. To me, it seems like a direct contradiction of the earlier part of the sentence. **************************************************************** From: Tucker Taft Sent: Tuesday, April 15, 2008 12:09 PM I actually think the sky is falling... ;-) **************************************************************** From: Adam Beneschan Sent: Tuesday, April 15, 2008 12:13 PM > I've never been able to make sense of that "but not in place of" wording. > To me, it seems like a direct contradiction of the earlier part of the > sentence. My interpretation would be to prohibit things like: if X > 5 then pragma List (On); else X := X + 1; end if; Here, the pragma is being substituted for ("in place of") a , replacing it; and since there are no statements left in the , which must have at least one , the syntax is now violated. I think "at the place of" means, in effect, "inserted before", but I can see how the actual wording in the RM could be misinterpreted. But in any case, that's what it seems to mean, to me. Maybe a better example, that doesn't involve a list of things in curly braces: select pragma List (On); -- legal, since it is at the place of -- but not in -- place of it T.Entry_1; or pragma List (Off); -- illegal, since it is "in place of" the -- end select; **************************************************************** From: Tucker Taft Sent: Tuesday, April 15, 2008 1:24 PM I think Bob understands the intent, but just doesn't think it is clearly worded. Another way to look at it is if you erase all the pragmas, the program must still be syntactically legal. In any case, as far as I know, compilers are in pretty good agreement about pragma placement. I don't remember seeing any recent complaints about this. So this is clearly more of a debate about clarity of wording than a real portability issue. **************************************************************** From: Randy Brukardt Sent: Tuesday, April 15, 2008 1:55 PM How do we know this? I presume that you mean that there is a lack of complaints. But that doesn't prove much: the lack of complaints may be more due to the combination of rarity of pragma placement and rarity of porting of code. It's not like there are an extensive set of ACATS tests trying every possible pragma placement... **************************************************************** From: Tucker Taft Sent: Tuesday, April 15, 2008 2:12 PM I guess this sounds more like a theoretical concern than a real user issue. I suppose you are right that there may be non-portability in corner cases, but I don't think we should go around looking for problems unless a user is having a real difficulty. **************************************************************** From: Robert A. Duff Sent: Tuesday, April 15, 2008 3:06 PM > I think Bob understands the intent, but just doesn't think it is > clearly worded. Another way to look at it is if you erase all the > pragmas, the program must still be syntactically legal. Yes. > In any case, as far as I know, compilers are in pretty good agreement > about pragma placement. I don't remember seeing any recent complaints > about this. So this is clearly more of a debate about clarity of > wording than a real portability issue. Well, apparently Adam copied this issue from somebody on comp.lang.ada. I looked at that thread, and it seems somebody is trying to write an Ada parser, and was genuinely confused as to what this pragma-wording meant. I have some sympathy for that, since I was genuinely confused about it back in 1983 or thereabouts. He also grumbled about the fact that the Ada syntax is ambiguous, and some other stuff that I don't fully understand. I have no idea why he's writing an Ada parser (Writing an Ada compiler? Writing some sort of Ada-processing tool? Just for the fun of it?). I have no opinion as to whether the ARG should take some action or not. **************************************************************** From: Pascal Leroy Sent: Tuesday, April 15, 2008 3:06 PM > * At any place where the syntax rules allow a construct defined by > a syntactic category whose name ends with "declaration", > "statement", "clause", or "alternative", or one of the syntactic > categories variant or exception_handler; but not in place of > such a construct. Also at any place where a compilation_unit > would be allowed. I have never understood this rule either, but for a different reason. Surely the syntax rules do allow a declaration (an entry_declaration) within a task_specification. Of course to find that out you have to follow several grammar productions. But then the rule above doesn't say that you don't get to traverse grammar productions. So from the words of the RM I have no idea whether the pragma is legal or not. Another problem with this rule is of course that it is likely to break when we change the syntax rules in some distant part of the RM. I don't share Tuck's optimism: for all I know, compilers may actually differ with respect to the placement of pragmas in obscure cases. In fact, I have a vague recollection of changing the Rational parser a few years ago because someone was trying to port code developed with GNAT, and they had a pragma in a place where we didn't allow pragmas. So I would welcome a rewrite of the silly rule above (but I'm not volunteering). **************************************************************** From: Jeffery R. Carter Sent: Tuesday, April 15, 2008 4:41 PM > I think Chris Noonan, on comp.lang.ada, has a point about this code > fragment (although I strongly disagree with his conclusion that the > sky is falling): > > task type TT is > pragma priority(12); > end TT; ARM D.1 says "A Priority pragma is allowed ... immediately within a task_definition .... ... At most one such pragma shall appear within a given construct." So it seems clear that this pragma is allowed here. The question is whether 2.8 allows it to appear alone. 2.8 also says "Additional syntax rules and placement restrictions exist for specific pragmas." I guess the question is then whether such additional rules and restrictions may relax the "not in place of" rule, which it may be argued D.1 does for pragma Priority. ****************************************************************