Skip to content

Commit 0287839

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

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
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) labels. 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+
occurr 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``, denoting a statement
68+
immediately within a sequence of statement enclosing the ``'At`` attribute
69+
reference. (visibility as defined by Ada RM is not strict enough,
70+
as ``statement_identifier`` are implicitly declared in innermost declare block)
71+
Within that enclosing sequence, the ``'At`` attribute shall occurr within a
72+
statement of the sequence that occurrs after the ``statement_identifier``
73+
it references. Furthermore, the ``statement_identifier`` referenced by
74+
an ``'At`` attribute and the attribute itself shall have the same
75+
innermost enclosing body.
76+
77+
The attribute ``'At`` denotes a constant that is implicitly declared at
78+
the label, following the same rules as local declarations without blocks.
79+
The declaration of the constant is the same as what would be declared for
80+
an unconditionally evaluated ``'Old`` attribute (ARM 26.*/4). In particular,
81+
for tagged types, the constant renames a class-wide temporary in order to
82+
preserve the tag.
83+
84+
The prefix of an ``'At`` attribute reference shall only reference entities
85+
visible at the location of the referenced ``statement_identifier``, or declared
86+
within the prefix itself. It shall not contains a ``'Loop_Entry`` reference
87+
without an explicit loop name. If the prefix of an ``'At`` attribute reference contains
88+
another ``'At`` attribute reference, or a ``'Loop_Entry`` reference (with an explicit
89+
loop name) the inner reference shall be legal at the location of the
90+
``statement_identifier`` referenced by the outer attribute. Similarly, if the
91+
prefix of an ``'Loop_Entry`` attribute reference contains a ``'At`` attribute reference,
92+
the ``'At`` reference shall be legal at the location immediately before the referenced
93+
loop.
94+
(Explanation: the reference should be legal and keep the same meaning when the expression
95+
of the surrounding reference is moved to the implicit declaration point).
96+
97+
The prefix of an ``'At`` attribute reference which is potentially unevaluated
98+
within the outermost enclosing expression shall statically name an entity,
99+
unless the pragma Unevaluated_Use_Of_Old is set to a value that would relax
100+
the matching restriction for attributes ``'Old``/``'Loop_Entry``.

0 commit comments

Comments
 (0)