Skip to content

Commit 4146cc3

Browse files
Petr BauchPetr Bauch
Petr Bauch
authored and
Petr Bauch
committed
slicer: add function path slicer
This slicer keeps any function in the program, in case it is backward or forward reachable from the target function. The analysis can be repeated for multiple functions. Note: This implementation cannot deal with order of function calls, e.g. if functions a,b and c should be kept, then a path that has a, which calls c, which calls b will also be kept. However, path where not all functions will be called, will be dropped.
1 parent 92793ca commit 4146cc3

File tree

8 files changed

+180
-12
lines changed

8 files changed

+180
-12
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
void a()
2+
{
3+
int e;
4+
}
5+
6+
void b()
7+
{
8+
double f;
9+
if(f == 0)
10+
a();
11+
}
12+
13+
void c()
14+
{
15+
int d;
16+
}
17+
18+
int main()
19+
{
20+
int k;
21+
if(k == 0)
22+
{
23+
int l;
24+
a();
25+
c();
26+
}
27+
else
28+
{
29+
b();
30+
}
31+
int n;
32+
a();
33+
return n;
34+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
main.c
3+
--fp-reachability-slice c
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
1: ASSUME FALSE
7+
dead e;
8+
dead d;
9+
--
10+
^warning: ignoring
11+
dead f;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
void a()
2+
{
3+
int e;
4+
}
5+
6+
void b()
7+
{
8+
double f;
9+
if(f == 0)
10+
a();
11+
}
12+
13+
void c()
14+
{
15+
int d;
16+
}
17+
18+
int main()
19+
{
20+
int k;
21+
if(k == 0)
22+
{
23+
int l;
24+
a();
25+
c();
26+
}
27+
else
28+
{
29+
b();
30+
}
31+
int n;
32+
a();
33+
return n;
34+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
main.c
3+
--fp-reachability-slice a,c
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
dead d;
7+
dead e;
8+
--
9+
^warning: ignoring
10+
dead f;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
void a()
2+
{
3+
int e;
4+
}
5+
6+
void b()
7+
{
8+
double f;
9+
if(f == 0)
10+
a();
11+
}
12+
13+
void c()
14+
{
15+
int d;
16+
}
17+
18+
int main()
19+
{
20+
int k;
21+
if(k == 0)
22+
{
23+
int l;
24+
a();
25+
c();
26+
}
27+
else
28+
{
29+
b();
30+
}
31+
int n;
32+
a();
33+
return n;
34+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
main.c
3+
--fp-reachability-slice b,c
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
1 file main.c line 34
7+
--
8+
^warning: ignoring
9+
dead d;
10+
dead e;
11+
dead f;

src/goto-instrument/reachability_slicer.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@ Author: Daniel Kroening, [email protected]
1717

1818
#include <stack>
1919

20+
#include <goto-programs/cfg.h>
21+
#include <goto-programs/remove_calls_no_body.h>
2022
#include <goto-programs/remove_skip.h>
2123
#include <goto-programs/remove_unreachable.h>
22-
#include <goto-programs/cfg.h>
24+
25+
#include "util/message.h"
2326

2427
#include "full_slicer_class.h"
2528
#include "reachability_slicer_class.h"
@@ -91,8 +94,7 @@ void reachability_slicert::fixedpoint_to_assertions(
9194
"all function return edges should point to the successor of a "
9295
"FUNCTION_CALL instruction");
9396
stack.emplace_back(edge.first, true);
94-
stack.emplace_back(
95-
cfg.entry_map[std::prev(node.PC)], caller_is_known);
97+
stack.emplace_back(cfg.entry_map[std::prev(node.PC)], caller_is_known);
9698
}
9799
else if(pred_node.PC->is_function_call())
98100
{
@@ -193,7 +195,7 @@ void reachability_slicert::slice(goto_functionst &goto_functions)
193195
{
194196
Forall_goto_program_instructions(i_it, f_it->second.body)
195197
{
196-
const cfgt::nodet &e=cfg[cfg.entry_map[i_it]];
198+
cfgt::nodet &e = cfg[cfg.entry_map[i_it]];
197199
if(
198200
!e.reaches_assertion && !e.reachable_from_assertion &&
199201
!i_it->is_end_function())
@@ -240,6 +242,31 @@ void reachability_slicer(
240242
s(goto_model.goto_functions, p, include_forward_reachability);
241243
}
242244

245+
/// Perform reachability slicing on goto_model for selected functions.
246+
/// \param goto_model Goto program to slice
247+
/// \param functions_list The functions relevant for the slicing (i.e. starting
248+
/// point for the search in the cfg). Anything that is reachable in the CFG
249+
/// starting from these functions will be kept.
250+
void function_path_reachability_slicer(
251+
goto_modelt &goto_model,
252+
const std::string &functions_list)
253+
{
254+
std::istringstream functions_stream(functions_list);
255+
std::string single_function;
256+
while(std::getline(functions_stream, single_function, ','))
257+
{
258+
in_function_criteriont matching_criterion(single_function);
259+
reachability_slicert slicer;
260+
slicer(goto_model.goto_functions, matching_criterion, true);
261+
}
262+
263+
remove_calls_no_bodyt remove_calls_no_body;
264+
remove_calls_no_body(goto_model.goto_functions);
265+
266+
goto_model.goto_functions.update();
267+
goto_model.goto_functions.compute_loop_numbers();
268+
}
269+
243270
/// Perform reachability slicing on goto_model, with respect to criterion
244271
/// comprising all properties. Only instructions from which the criterion
245272
/// is reachable will be kept.

src/goto-instrument/reachability_slicer.h

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ void reachability_slicer(
2323
goto_modelt &,
2424
const std::list<std::string> &properties);
2525

26+
void function_path_reachability_slicer(
27+
goto_modelt &goto_model,
28+
const std::string &functions_list);
29+
2630
void reachability_slicer(
2731
goto_modelt &,
2832
const bool include_forward_reachability);
@@ -33,13 +37,16 @@ void reachability_slicer(
3337
const bool include_forward_reachability);
3438

3539
// clang-format off
36-
#define OPT_REACHABILITY_SLICER \
37-
"(reachability-slice)(reachability-slice-fb)" // NOLINT(*)
38-
39-
#define HELP_REACHABILITY_SLICER \
40-
" --reachability-slice remove instructions that cannot appear on\n" \
41-
" a trace from entry point to a property\n" \
42-
" --reachability-slice-fb remove instructions that cannot appear on\n" \
43-
" a trace from entry point through a property\n" // NOLINT(*)
40+
#define OPT_REACHABILITY_SLICER \
41+
"(fp-reachability-slice):(reachability-slice)(reachability-slice-fb)" // NOLINT(*)
42+
43+
#define HELP_REACHABILITY_SLICER \
44+
" --fp-reachability-slice <f> remove instructions that cannot appear on a " \
45+
"trace that visits all given functions. The list of functions has to be " \
46+
"given as a comma separated list.\n" \
47+
" --reachability-slice remove instructions that cannot appear on a " \
48+
"trace from entry point to a property\n" \
49+
" --reachability-slice-fb remove instructions that cannot appear on a " \
50+
"trace from entry point through a property\n" // NOLINT(*)
4451
// clang-format on
4552
#endif // CPROVER_GOTO_INSTRUMENT_REACHABILITY_SLICER_H

0 commit comments

Comments
 (0)