|
| 1 | +Feature Name: value_at_labels |
| 2 | +Start Date: 2025-10-30 |
| 3 | +Status: Planning |
| 4 | + |
| 5 | +Summary |
| 6 | +======= |
| 7 | + |
| 8 | +This RFC introduces a new attribute, called ``At`` that can be applied to |
| 9 | +an expression to refer to a copy of its value saved at a preceding label. |
| 10 | +This attribute can be thought as a generalization of the ``Old`` and |
| 11 | +``Loop_Entry`` attributes. |
| 12 | + |
| 13 | +Motivation |
| 14 | +========== |
| 15 | + |
| 16 | +Complex proof in GNATprove can require writing intermediate assertions to |
| 17 | +guide proof, relating values of the program state between multiple steps. |
| 18 | +Currently, the only way to state anything about these values is to manually |
| 19 | +save the required values in ghost constant declarations. The ``At`` |
| 20 | +attribute is intended to provide concise syntactic sugar to automate that |
| 21 | +process. The user would only need to add a label at the preceding control |
| 22 | +flow point, rather than full ghost constant declarations for everything that |
| 23 | +need to be saved. |
| 24 | + |
| 25 | + |
| 26 | +Guide-level explanation |
| 27 | +======================= |
| 28 | + |
| 29 | +The ``'At`` attribute takes a label as argument, and can be used on |
| 30 | +arbitrary expressions to denote a constant declared at that label, |
| 31 | +and initialized with that expression. A program using the ``'At`` |
| 32 | +attribute is equivalent to a program declaring the constant explicitly |
| 33 | +at that label. As an example, the following code: |
| 34 | + |
| 35 | +```ada |
| 36 | +X := 1; |
| 37 | +<<My_Label>> |
| 38 | +X := 2; |
| 39 | +pragma Assert ((X-1)'At (My_Label) = 0); |
| 40 | +``` |
| 41 | + |
| 42 | +is equivalent to |
| 43 | + |
| 44 | +```ada |
| 45 | +X := 1; |
| 46 | +declare |
| 47 | + Compiler_Generated_Unique_Name : constant Integer := (X-1); |
| 48 | +begin |
| 49 | + X := 2; |
| 50 | + pragma Assert (Compiler_Generated_Unique_Name = 0); |
| 51 | +end; |
| 52 | +``` |
| 53 | + |
| 54 | +That equivalence implies that it is not allowed to refer to the value of |
| 55 | +a constant at a non-visible (or following) label. The equivalence also |
| 56 | +means that the scope of the constant is the surrounding sequence of |
| 57 | +statements of the label. In particular, associated finalization will |
| 58 | +occur at the end of the sequence, rather than immediately after the |
| 59 | +reference. |
| 60 | + |
| 61 | + |
| 62 | +Reference-level explanation |
| 63 | +=========================== |
| 64 | + |
| 65 | +The attribute ``'At`` can be applied to any subexpression, and takes |
| 66 | +a ``statement_identifier`` as parameter. That ``statement_identifier`` |
| 67 | +shall refer to a visible ``statement_identifier``. The innermost sequence |
| 68 | +of statements enclosing the ``statement_identifier`` shall also enclose |
| 69 | +the ``'At`` attribute. Furthermore, if the ``'At`` attribute is enclosed by |
| 70 | +an accept_statement or a body, then the ``statement_identifier`` shall not |
| 71 | +be outside this enclosing construct. The preceding are the same rules as for |
| 72 | +``goto`` statements; in addition, within the innermost sequence of statement |
| 73 | +enclosing both, the ``'At`` attribute shall occurs in a statement occurring |
| 74 | +after the ``statement_identifier`` it references. |
| 75 | + |
| 76 | +The attribute ``'At`` denotes a constant that is implicitly declared at |
| 77 | +the label, following the same rules as local declarations without blocks. |
| 78 | +The declaration of the constant is the same as what would be declared for |
| 79 | +an unconditionally evaluated ``'Old`` attribute (ARM 26.*/4). In particular, |
| 80 | +for tagged types, the constant renames a class-wide temporary in order to |
| 81 | +preserve the tag. |
| 82 | + |
| 83 | +The prefix of an ``'At`` attribute reference shall only reference entities |
| 84 | +visible at the location of the referenced ``statement_identifier``, or declared |
| 85 | +within the prefix itself. It shall not contains a ``'Loop_Entry`` reference |
| 86 | +without an explicit loop name. If the prefix of an ``'At`` attribute reference contains |
| 87 | +another ``'At`` attribute reference, or a ``'Loop_Entry`` reference (with an explicit |
| 88 | +loop name) the inner reference shall be legal at the location of the |
| 89 | +``statement_identifier`` referenced by the outer attribute. Similarly, if the |
| 90 | +prefix of an ``'Loop_Entry`` attribute reference contains a ``'At`` attribute reference, |
| 91 | +the ``'At`` reference shall be legal at the location immediately before the referenced |
| 92 | +loop. |
| 93 | +(Explanation: the reference should be legal and keep the same meaning when the expression |
| 94 | + of the surrounding reference is moved to the implicit declaration point). |
| 95 | + |
| 96 | +The prefix of an ``'At`` attribute reference which is potentially unevaluated |
| 97 | +within the outermost enclosing expression shall statically name an entity, |
| 98 | +unless the pragma Unevaluated_Use_Of_Old is set to a value that would relax |
| 99 | +the matching restriction for attributes ``'Old``/``'Loop_Entry``. |
0 commit comments