AI22-0064-1

!standard 4.4(8)                                        23-03-22  AI22-0064-1/01

!standard 4.4(9.1/5)

!standard 4.4(10.1/5)

!standard 8.6(17.1/5)

!class binding interpretation 23-03-22

!status work item 23-02-22

!status received 23-02-22

!priority Low

!difficulty Easy

!qualifier Omission

!subject Obvious rules that should be stated

!summary

Parenthesized expressions have the obvious resolution and evaluation rules.

A direct_name representing a discriminant or protected component is interpreted as the discriminant or protected component of the current instance of the enclosing type.

!issue

In AI12-0066-1, we decided not to fix certain obvious missing rules in Ada. In particular, we didn't define the properties of a parenthesized expression. But we've continued to nibble at that in later AIs, adding a definition for parenthesized expression and the term operative constituent. We should complete the job rather than leaving these rules to the imagination.

Similarly, the meaning of direct_names of discriminants and protected components matters in the interpretation of many rules, including Legality Rules and various semantic rules. But we've essentially left the definition of this part of the language to the ACATS. This should be fixed.

!recommendation

(See Summary.)

!wording

Add after 4.4(8): [in Name Resolution Rules]

A primary that is an expression surrounded by ( and ) is known as a parenthesized expression; the expression of a parenthesized expression is the operand of the parenthesized expression. The expected type of the operand of a parenthesized expression is that of the parenthesized expression as a whole.

[Editor's note: we define the meaning of "operand" for type conversions and qualified expressions, we ought to do so for parenthesized expressions as well, especially as 4.4(9.4/5) uses "operand" with parenthesized expressions.]

Delete 4.4(9.1/5). [moved above]

Add after 4.4(10.1/5): [in Dynamic Semantics]

The evaluation of a parenthesized expression evaluates the operand of the parenthesized expression

AARM Ramification: There is no other effect; there is no check or conversion associated with this evaluation. Of course, the parenthesized expression could be subject to a check or conversion depending on the context in which it is used.

[Editor's note: I find it odd that 4.4 doesn't say anything about evaluation of an expression, but most of the individual constructs have such rules given in their respective sections. Of course, there are no such rules elsewhere for parenthesized expressions, so I add one here. The wording is based on that for qualified expressions. I don't talk about the result as it is unchanged and the more said, the more likely an error is introduced. Is the second sentence of the AARM note helpful?]

Add after 8.6(17.1/5): [this is directly after the definition of "current instance"]

AARM Discussion: Such usage names are direct_names without any prefix. If there is a prefix, then the usage name denotes the component or discriminant of the object named in the prefix, and this rule does not apply even inside of the declarative region of the type.

[Editor's note: This echoes the definition of current instance, so it will fit well. I'm assuming that a protected or task body is considered part of the declaration region of the type_declaration (it ought to be so the current instance rule works), so we don't need to mention those bodies.]

!discussion

The addition of the term parenthesized expression and the term operative constituent were fixes in Ada 2022 to ensure that properties are correctly defined for various related constructs including parenthesized expressions. For instance, we have taken great care to ensure that whether an entity is newly constructed flows through parenthesized expressions. It seems weird to then ignore just the name resolution and evaluation of the construct.

The properties of the current instance affects legality of component references as well as the dynamic semantics. For example:

type Acc is access all Some_Type;
protected Stack is
   procedure Push (Item : in Acc);
   function Pop return Acc;
private
   Stack_Head : Acc := null;
end Stack;

protected body Stack is
   function Pop return Acc is
      Temp : Acc := Stack_Head;
   begin
      Stack_Head := Stack_Head.Next; -- Illegal.
      return Temp;
   end Pop;
   procedure Push (Item : in Acc) is
   begin
      Item.Next := Stack_Head;
      Stack_Head := Item; -- OK.
   end Push;
end Stack;

 

The line marked Illegal isn't allowed because Stack_Head refers to the protected component of the current instance of Stack, and the current instance is a constant inside a protected function.

But there is no rule in the Standard that says that Stack_Head refers to the component of the current instance.

Similarly, in

type Rec (D : Natural) is record
   S : String (1 .. D); -- D here is that of the current instance.
end record;

we ought to know that D refers to the discriminant of the current instance.

Because of this, this seems too important to leave to the ACATS to define (and the ACATS has a number of tests, some as old as the ACVC, that test this expectation).

[Editor's note: The other items of AI12-0066-1 are covered in AI22-0067-1 and AI22-0066-1 (which is the counterpart of AI12-0066-1 for Ada 2022).]

!ACATS test

These rules have been assumed by the ACATS going back to the original ACVC; further testing should not be needed.

!appendix