comp.lang.ada
 help / color / mirror / Atom feed
* suppress "unspecified order" error in gnat?
@ 2019-03-15 23:50 Stephen Leake
  2019-03-18 23:25 ` Randy Brukardt
  0 siblings, 1 reply; 2+ messages in thread
From: Stephen Leake @ 2019-03-15 23:50 UTC (permalink / raw)


I'd like to compile the following:

         New_Nonterm : constant Valid_Node_Index := Tree.Add_Nonterm
           ((+nonterminal_ID, 0),
            (1 => Tree.Add_Identifier (+IDENTIFIER_ID, New_Identifier),
             2 => Tree.Add_Terminal (+COLON_ID),
             3 => RHS_Alt_Node,
             4 => Tree.Add_Nonterm
               ((+semicolon_opt_ID, 0),
                (1 => Tree.Add_Terminal (+SEMICOLON_ID)))));

but GNAT complains:

wisitoken_grammar_runtime.adb:715:19: value of actual may be affected by call in other actual because they are evaluated in unspecified order

Here "Tree" is a syntax tree, and the various Tree.Add_* functions insert items in the tree and return a tree node id. 

In this case, it does not matter what order the aggregate elements are evaluated in. Normally I applaud this error, but I'd like to turn it off in this case.

Applying 'pragma Warnings' doesn't work, because this is not a warning; it's an error.

Surprisingly, I can write a subprogram to work around this; the above becomes

         New_Nonterm : constant Valid_Node_Index := Add_Nonterm
           ((+nonterminal_ID, 0),
            Child_1 => Tree.Add_Identifier (+IDENTIFIER_ID, New_Identifier),
            Child_2 => Tree.Add_Terminal (+COLON_ID),
            Child_3 => RHS_Alt_Node,
            Child_4 => Tree.Add_Nonterm
              ((+semicolon_opt_ID, 0),
               (1   => Tree.Add_Terminal (+SEMICOLON_ID))));

Note that Child_1 .. Child_4 are also evaluated in an arbitrary order, according to the ARM (6.4 10). Maybe GNAT imposes an order here, but not in an aggregate?

But I have similar statements that are harder to work around:

         Tree.Set_Children
           (Comp_Unit_List_Tail,
            (1 => Tree.Add_Nonterm
               ((+compilation_unit_list_ID, 0),
                (1 => Tree.Add_Nonterm
                   ((+compilation_unit_ID, 1),
                    (1 => New_Nonterm))))));


Here I need to declare some local vars to enforce an order. Ugly. This aggregate nicely reflects the actual tree structure; morphing it to use local vars destroys that.


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: suppress "unspecified order" error in gnat?
  2019-03-15 23:50 suppress "unspecified order" error in gnat? Stephen Leake
@ 2019-03-18 23:25 ` Randy Brukardt
  0 siblings, 0 replies; 2+ messages in thread
From: Randy Brukardt @ 2019-03-18 23:25 UTC (permalink / raw)


"Stephen Leake" <stephen_leake@stephe-leake.org> wrote in message 
news:f09c8b98-5f65-4a63-bbc7-b192ad906113@googlegroups.com...
> I'd like to compile the following:
>
>         New_Nonterm : constant Valid_Node_Index := Tree.Add_Nonterm
>           ((+nonterminal_ID, 0),
>            (1 => Tree.Add_Identifier (+IDENTIFIER_ID, New_Identifier),
>             2 => Tree.Add_Terminal (+COLON_ID),
>             3 => RHS_Alt_Node,
>             4 => Tree.Add_Nonterm
>               ((+semicolon_opt_ID, 0),
>                (1 => Tree.Add_Terminal (+SEMICOLON_ID)))));
>
> but GNAT complains:
>
> wisitoken_grammar_runtime.adb:715:19: value of actual may be affected by 
> call in other actual because they are evaluated in unspecified order
>
> Here "Tree" is a syntax tree, and the various Tree.Add_* functions insert 
> items in the tree and return a tree node id.
>
> In this case, it does not matter what order the aggregate elements are 
> evaluated in. Normally I applaud this error, but I'd like to turn it off 
> in this case.

This was the compromize that let us get "in out" parameters in functions 
added to the language. It's an error, but it is purposely designed to be 
conservative. So it should happen rarely (if at all) in code where it 
doesn't matter.

The rule is strong for functions with in out parameters and weak otherwise. 
It shouldn't trigger unless you have a bunch of functions with "in out" 
parameters or you did something obviously wrong. I don't see either of those 
in the above, although it's hard to tell without any compilable code. (Note: 
many of us complain about non-compilable examples from outsiders -- that 
applies to us as well!! :-)

GNAT was known to have enforced this rule incorrectly; I ran into an error 
like the above in some of my own code, and when I analyzed the code, it 
turned out to be legal (and also that there was a minor bug in the Standard, 
big surprise - it was requiring checks on composite parameters to procedures 
that had at least 3 paraameters, two of which were in out elementary). We've 
fixed the bug in the Standard, I have no idea if the bugs in GNAT were fixed 
(although I did report my specific case and I think that was fixed).

There never has been ACATS tests for this rule written, and clearly there 
needs to be. If I had an unlimited budget... :-)

> Applying 'pragma Warnings' doesn't work, because this is not a warning; 
> it's an error.

Duh. :-)

> Surprisingly, I can write a subprogram to work around this; the above 
> becomes
>
>         New_Nonterm : constant Valid_Node_Index := Add_Nonterm
>           ((+nonterminal_ID, 0),
>            Child_1 => Tree.Add_Identifier (+IDENTIFIER_ID, 
> New_Identifier),
>            Child_2 => Tree.Add_Terminal (+COLON_ID),
>            Child_3 => RHS_Alt_Node,
>            Child_4 => Tree.Add_Nonterm
>              ((+semicolon_opt_ID, 0),
>               (1   => Tree.Add_Terminal (+SEMICOLON_ID))));

I don't see any difference with this that the other except that the 
component names are properly given here. Again, a full example might make it 
clearer what the heck you are talking about here.

In any case, the rule for the parameters of a subprogram call and those for 
an aggregate are the same, so if you are getting different results, I'd 
expect a GNAT bug. But it's hard to be certain without running the actual 
case through the 2 pages of rules in 6.4.1. That requires a complete example 
(yes, broken record ... ;-).

                        Randy.


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-03-18 23:25 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-15 23:50 suppress "unspecified order" error in gnat? Stephen Leake
2019-03-18 23:25 ` Randy Brukardt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox