Skip to content

Commit 80a8f4a

Browse files
Proposal for referring to values at labels
1 parent 6c9e744 commit 80a8f4a

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
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

Comments
 (0)