Skip to content

Commit 5c558e7

Browse files
committed
Allow loop number as index in Crangler
1 parent 78efc2c commit 5c558e7

File tree

4 files changed

+59
-4
lines changed

4 files changed

+59
-4
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
int foo(int *arr, int size)
2+
{
3+
arr[0] = 0;
4+
arr[size - 1] = 0;
5+
for(int i = 0; i < 2; i++)
6+
{
7+
arr[i] = 0;
8+
}
9+
10+
int i = 0;
11+
while(i < 2)
12+
{
13+
arr[i] = 0;
14+
i++;
15+
}
16+
17+
return size < 10 ? 0 : arr[5];
18+
}
19+
20+
int main()
21+
{
22+
int arr[10];
23+
int retval = foo(arr, 10);
24+
__CPROVER_assert(retval == arr[5], "should succeed");
25+
return 0;
26+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
test.json
3+
4+
^\s+while\(i \< 2\) \_\_CPROVER\_loop\_invariant
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
--
8+
^\s+for\(int i = 0; i \< 2; i\+\+\) \_\_CPROVER
9+
--
10+
Annotate loop invariant only to the second loop.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"sources": [
3+
"main.c"
4+
],
5+
"functions": [
6+
{
7+
"foo": [
8+
"loop 2 invariant 1==1"
9+
]
10+
}
11+
],
12+
"output": "stdout"
13+
}

src/crangler/c_wrangler.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,8 @@ void c_wranglert::configure_functions(const jsont &config)
213213
function_config.assertions.emplace_back(split[1], rest.str());
214214
}
215215
else if(
216-
(split[0] == "for" && split.size() >= 3 && split[2] == "invariant") ||
217-
(split[0] == "while" && split.size() >= 3 && split[2] == "invariant"))
216+
(split[0] == "for" || split[0] == "while" || split[0] == "loop") &&
217+
split.size() >= 3 && split[2] == "invariant")
218218
{
219219
std::ostringstream rest;
220220
join_strings(rest, split.begin() + 3, split.end(), ' ');
@@ -434,7 +434,10 @@ static void mangle_function(
434434
{
435435
while_count++;
436436
const auto &invariant =
437-
loop_invariants["while" + std::to_string(while_count)];
437+
loop_invariants.count("while" + std::to_string(while_count))
438+
? loop_invariants["while" + std::to_string(while_count)]
439+
: loop_invariants
440+
["loop" + std::to_string(while_count + for_count)];
438441

439442
if(!invariant.empty())
440443
{
@@ -449,7 +452,10 @@ static void mangle_function(
449452
{
450453
for_count++;
451454
const auto &invariant =
452-
loop_invariants["for" + std::to_string(for_count)];
455+
loop_invariants.count("for" + std::to_string(for_count))
456+
? loop_invariants["for" + std::to_string(for_count)]
457+
: loop_invariants
458+
["loop" + std::to_string(while_count + for_count)];
453459

454460
if(!invariant.empty())
455461
{

0 commit comments

Comments
 (0)