Skip to content

Commit 5c83574

Browse files
authored
Merge pull request #7060 from padhi-aws-forks/history-vars-fix
CONTRACTS: Allow `ID_index` expressions in history variables
2 parents 8fbba35 + 87a8ddb commit 5c83574

File tree

6 files changed

+68
-1
lines changed

6 files changed

+68
-1
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include <assert.h>
2+
3+
int main()
4+
{
5+
int i, n, x[10];
6+
__CPROVER_assume(x[0] == x[9]);
7+
while(i < n)
8+
__CPROVER_loop_invariant(x[0] == __CPROVER_loop_entry(x[0]))
9+
{
10+
x[0] = x[9] - 1;
11+
x[0]++;
12+
}
13+
assert(x[0] == x[9]);
14+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
main.c
3+
--apply-loop-contracts
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^Tracking history of index expressions is not supported yet\.
9+
--
10+
This test checks that `ID_index` expressions are allowed within history variables.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include <assert.h>
2+
3+
int foo(int x)
4+
{
5+
return x;
6+
}
7+
8+
int main()
9+
{
10+
int i, n, x[10];
11+
__CPROVER_assume(x[0] == x[9]);
12+
while(i < n)
13+
__CPROVER_loop_invariant(x[0] == __CPROVER_loop_entry(foo(x[0])))
14+
{
15+
x[0] = x[9] - 1;
16+
x[0]++;
17+
}
18+
assert(x[0] == x[9]);
19+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
main.c
3+
--apply-loop-contracts
4+
^main.c.* error: Tracking history of side_effect expressions is not supported yet.$
5+
^CONVERSION ERROR$
6+
^EXIT=(1|64)$
7+
^SIGNAL=0$
8+
--
9+
--
10+
This test ensures that expressions with side effect, such as function calls,
11+
may not be used in history variables.

src/ansi-c/c_typecheck_expr.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2732,6 +2732,18 @@ exprt c_typecheck_baset::do_special_functions(
27322732
throw 0;
27332733
}
27342734

2735+
const auto &param_id = expr.arguments().front().id();
2736+
if(!(param_id == ID_dereference || param_id == ID_member ||
2737+
param_id == ID_symbol || param_id == ID_ptrmember ||
2738+
param_id == ID_constant || param_id == ID_typecast ||
2739+
param_id == ID_index))
2740+
{
2741+
error().source_location = f_op.source_location();
2742+
error() << "Tracking history of " << param_id
2743+
<< " expressions is not supported yet." << eom;
2744+
throw 0;
2745+
}
2746+
27352747
irep_idt id = identifier == CPROVER_PREFIX "old" ? ID_old : ID_loop_entry;
27362748

27372749
history_exprt old_expr(expr.arguments()[0], id);

src/goto-instrument/contracts/contracts.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -664,7 +664,8 @@ void code_contractst::replace_history_parameter(
664664
const auto &id = parameter.id();
665665
if(
666666
id == ID_dereference || id == ID_member || id == ID_symbol ||
667-
id == ID_ptrmember || id == ID_constant || id == ID_typecast)
667+
id == ID_ptrmember || id == ID_constant || id == ID_typecast ||
668+
id == ID_index)
668669
{
669670
auto it = parameter2history.find(parameter);
670671

0 commit comments

Comments
 (0)