Version 1.1 of ai05s/ai05-0100-1.txt
!standard 2.8(6) 08-05-28 AI05-0100-1/01
!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
!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
Replace 2.8(7) by:
* At a place where a pragma would have been allowed by the preceeding rule
if some legal syntactic item had been given before the pragma, but not
if the pragma is the only item in a list that requires at least one item.
AARM Note: "Item" in this context means something like a statement or
declaration. The last part of the rule just means that a pragma
cannot replace some item that is required by the syntax (like a statement).
!discussion
Tucker suggested the principle that after erasing the pragmas, the program
should still be syntactically legal. That seems like a good principle to
follow. Another important principle would be that changing the Ada syntax
should not change where pragmas are allowed.
However, it will take someone cleverer than I to create wording that will
meet those goals. "Item" in my attempt above doesn't make much sense.
The best solution would be to put pragma into the syntax like it should have
been in the first place, and then adopt an English like the last part of the
rule above ("A pragma is illegal if it is the only item in a list that
requires at least one item.") But that would change a lot of the language
syntax.
--!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 <pragma> 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 <statement>,
replacing it; and since there are no statements left in the
<sequence_of_statements>, which must have at least one <statement>, 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
-- <entry_call_alternative> but not in
-- place of it
T.Entry_1;
or
pragma List (Off); -- illegal, since it is "in place of" the
-- <delay_alternative>
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.
****************************************************************
Questions? Ask the ACAA Technical Agent