Skip to content

Commit 3050c53

Browse files
thk123martin
thk123
authored and
martin
committed
Don't stop when recursion found
Since we are finding a fixed point we do the same things we do for loops when we find a recurssive function - we descend into it and carry on. Previously we were never doing the transforms from the recurssive function call to the start of the function meaning we would not realise it can be called with multiple parameters. Further, we weren't doing the transform from after the recursive function call onwards, meaning for some inputs it would incorrectly conclude the function never returned. Now we just do the transforms ignoring the fact it could be recursive. For the constants domain this is OK as a fixed point will be found quickly. For other domains we will need to implement some sort of widening. Included a test for recursion.
1 parent 93f2e1f commit 3050c53

File tree

4 files changed

+67
-13
lines changed

4 files changed

+67
-13
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#include <assert.h>
2+
3+
int bar(int other)
4+
{
5+
if(other > 0)
6+
{
7+
int value = bar(other - 1);
8+
return value + 1;
9+
}
10+
else
11+
{
12+
return 0;
13+
}
14+
}
15+
16+
int bar_clean(int other)
17+
{
18+
if(other > 0)
19+
{
20+
int value = bar_clean(other - 1);
21+
return value + 1;
22+
}
23+
else
24+
{
25+
return 0;
26+
}
27+
}
28+
29+
int fun(int changing, int constant)
30+
{
31+
if(changing > 0)
32+
{
33+
int value = fun(changing - 1, constant);
34+
return value;
35+
}
36+
else
37+
{
38+
return constant;
39+
}
40+
}
41+
42+
int main(int argc, char *argv[])
43+
{
44+
int x=3;
45+
int y=bar(x+1);
46+
assert(y==4); // Unknown in the constants domain
47+
48+
int y2 = bar(0);
49+
assert(y2==0); // Unknown since we are not sensitive to call domain
50+
51+
int z = bar_clean(0);
52+
assert(z==0); // Unknown as the function has parameter as top
53+
54+
int w = fun(5, 18);
55+
assert(w==18);
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
main.c
3+
--variable --pointers --arrays --structs --verify
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^\[main\.assertion\.1\] .* assertion y==4: Unknown$
7+
^\[main\.assertion\.2\] .* assertion y2==0: Unknown$
8+
^\[main\.assertion\.3\] .* assertion z==0: Success$
9+
^\[main\.assertion\.4\] .* assertion w==18: Success$
10+
--
11+
^warning: ignoring

src/analyses/ai.cpp

-10
Original file line numberDiff line numberDiff line change
@@ -459,14 +459,6 @@ bool ai_baset::do_function_call_rec(
459459
{
460460
const irep_idt &identifier=function.get(ID_identifier);
461461

462-
if(recursion_set.find(identifier)!=recursion_set.end())
463-
{
464-
// recursion detected!
465-
return new_data;
466-
}
467-
else
468-
recursion_set.insert(identifier);
469-
470462
goto_functionst::function_mapt::const_iterator it=
471463
goto_functions.function_map.find(identifier);
472464

@@ -479,8 +471,6 @@ bool ai_baset::do_function_call_rec(
479471
it,
480472
arguments,
481473
ns);
482-
483-
recursion_set.erase(identifier);
484474
}
485475
else if(function.id()==ID_if)
486476
{

src/analyses/ai.h

-3
Original file line numberDiff line numberDiff line change
@@ -311,9 +311,6 @@ class ai_baset
311311
const goto_functionst &goto_functions,
312312
const namespacet &ns);
313313

314-
typedef std::set<irep_idt> recursion_sett;
315-
recursion_sett recursion_set;
316-
317314
// function calls
318315
bool do_function_call_rec(
319316
locationt l_call, locationt l_return,

0 commit comments

Comments
 (0)