Skip to content

Commit 37f122c

Browse files
authored
Merge pull request #6505 from tautschnig/fix-reachability-slicer
Reachability slice requires function bodies
2 parents 643037e + 0359a87 commit 37f122c

File tree

10 files changed

+170
-62
lines changed

10 files changed

+170
-62
lines changed

jbmc/src/jbmc/jbmc_parse_options.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -962,18 +962,24 @@ bool jbmc_parse_optionst::process_goto_functions(
962962
log.status() << "Performing a forwards-backwards reachability slice"
963963
<< messaget::eom;
964964
if(cmdline.isset("property"))
965-
reachability_slicer(goto_model, cmdline.get_values("property"), true);
965+
{
966+
reachability_slicer(
967+
goto_model, cmdline.get_values("property"), true, ui_message_handler);
968+
}
966969
else
967-
reachability_slicer(goto_model, true);
970+
reachability_slicer(goto_model, true, ui_message_handler);
968971
}
969972

970973
if(cmdline.isset("reachability-slice"))
971974
{
972975
log.status() << "Performing a reachability slice" << messaget::eom;
973976
if(cmdline.isset("property"))
974-
reachability_slicer(goto_model, cmdline.get_values("property"));
977+
{
978+
reachability_slicer(
979+
goto_model, cmdline.get_values("property"), ui_message_handler);
980+
}
975981
else
976-
reachability_slicer(goto_model);
982+
reachability_slicer(goto_model, ui_message_handler);
977983
}
978984

979985
// full slice?
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include <stdlib.h>
2+
3+
void undefined_function();
4+
5+
void a()
6+
{
7+
undefined_function();
8+
}
9+
10+
void b()
11+
{
12+
int should_be_sliced_away;
13+
}
14+
15+
int main()
16+
{
17+
int *p = malloc(sizeof(int));
18+
a();
19+
__CPROVER_assert(0, "reach me");
20+
b();
21+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
main.c
3+
--reachability-slice
4+
Removing call to undefined_function, which has no body
5+
^VERIFICATION FAILED$
6+
^EXIT=10$
7+
^SIGNAL=0$
8+
--
9+
should_be_sliced_away

src/cbmc/cbmc_parse_options.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -944,19 +944,29 @@ bool cbmc_parse_optionst::process_goto_program(
944944
log.status() << "Performing a forwards-backwards reachability slice"
945945
<< messaget::eom;
946946
if(options.is_set("property"))
947+
{
947948
reachability_slicer(
948-
goto_model, options.get_list_option("property"), true);
949+
goto_model,
950+
options.get_list_option("property"),
951+
true,
952+
log.get_message_handler());
953+
}
949954
else
950-
reachability_slicer(goto_model, true);
955+
reachability_slicer(goto_model, true, log.get_message_handler());
951956
}
952957

953958
if(options.get_bool_option("reachability-slice"))
954959
{
955960
log.status() << "Performing a reachability slice" << messaget::eom;
956961
if(options.is_set("property"))
957-
reachability_slicer(goto_model, options.get_list_option("property"));
962+
{
963+
reachability_slicer(
964+
goto_model,
965+
options.get_list_option("property"),
966+
log.get_message_handler());
967+
}
958968
else
959-
reachability_slicer(goto_model);
969+
reachability_slicer(goto_model, log.get_message_handler());
960970
}
961971

962972
// full slice?

src/goto-instrument/goto_instrument_parse_options.cpp

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -841,7 +841,7 @@ int goto_instrument_parse_optionst::doit()
841841
log.status() << "Removing calls to functions without a body"
842842
<< messaget::eom;
843843
remove_calls_no_bodyt remove_calls_no_body;
844-
remove_calls_no_body(goto_model.goto_functions);
844+
remove_calls_no_body(goto_model.goto_functions, ui_message_handler);
845845

846846
log.status() << "Accelerating" << messaget::eom;
847847
guard_managert guard_manager;
@@ -1066,8 +1066,11 @@ void goto_instrument_parse_optionst::instrument_goto_program()
10661066

10671067
// we add the library in some cases, as some analyses benefit
10681068

1069-
if(cmdline.isset("add-library") ||
1070-
cmdline.isset("mm"))
1069+
if(
1070+
cmdline.isset("add-library") || cmdline.isset("mm") ||
1071+
cmdline.isset("reachability-slice") ||
1072+
cmdline.isset("reachability-slice-fb") ||
1073+
cmdline.isset("fp-reachability-slice"))
10711074
{
10721075
if(cmdline.isset("show-custom-bitvector-analysis") ||
10731076
cmdline.isset("custom-bitvector-analysis"))
@@ -1245,7 +1248,7 @@ void goto_instrument_parse_optionst::instrument_goto_program()
12451248
<< messaget::eom;
12461249

12471250
remove_calls_no_bodyt remove_calls_no_body;
1248-
remove_calls_no_body(goto_model.goto_functions);
1251+
remove_calls_no_body(goto_model.goto_functions, ui_message_handler);
12491252

12501253
goto_model.goto_functions.update();
12511254
goto_model.goto_functions.compute_loop_numbers();
@@ -1602,9 +1605,12 @@ void goto_instrument_parse_optionst::instrument_goto_program()
16021605
goto_model.goto_functions.update();
16031606

16041607
if(cmdline.isset("property"))
1605-
reachability_slicer(goto_model, cmdline.get_values("property"));
1608+
{
1609+
reachability_slicer(
1610+
goto_model, cmdline.get_values("property"), ui_message_handler);
1611+
}
16061612
else
1607-
reachability_slicer(goto_model);
1613+
reachability_slicer(goto_model, ui_message_handler);
16081614
}
16091615

16101616
if(cmdline.isset("fp-reachability-slice"))
@@ -1614,7 +1620,9 @@ void goto_instrument_parse_optionst::instrument_goto_program()
16141620
log.status() << "Performing a function pointer reachability slice"
16151621
<< messaget::eom;
16161622
function_path_reachability_slicer(
1617-
goto_model, cmdline.get_comma_separated_values("fp-reachability-slice"));
1623+
goto_model,
1624+
cmdline.get_comma_separated_values("fp-reachability-slice"),
1625+
ui_message_handler);
16181626
}
16191627

16201628
// full slice?
@@ -1687,9 +1695,12 @@ void goto_instrument_parse_optionst::instrument_goto_program()
16871695

16881696
log.status() << "Performing a reachability slice" << messaget::eom;
16891697
if(cmdline.isset("property"))
1690-
reachability_slicer(goto_model, cmdline.get_values("property"));
1698+
{
1699+
reachability_slicer(
1700+
goto_model, cmdline.get_values("property"), ui_message_handler);
1701+
}
16911702
else
1692-
reachability_slicer(goto_model);
1703+
reachability_slicer(goto_model, ui_message_handler);
16931704
}
16941705

16951706
if(cmdline.isset("ensure-one-backedge-per-target"))

src/goto-instrument/reachability_slicer.cpp

Lines changed: 62 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,46 @@ Author: Daniel Kroening, [email protected]
1313
/// (and possibly, depending on the parameters, keep those that can be reached
1414
/// from the criterion).
1515

16-
#include "reachability_slicer.h"
16+
#include "full_slicer_class.h"
17+
#include "reachability_slicer_class.h"
18+
19+
#include <util/exception_utils.h>
1720

1821
#include <goto-programs/cfg.h>
1922
#include <goto-programs/remove_calls_no_body.h>
2023
#include <goto-programs/remove_skip.h>
2124
#include <goto-programs/remove_unreachable.h>
2225

23-
#include <util/exception_utils.h>
26+
#include <analyses/is_threaded.h>
2427

25-
#include "full_slicer_class.h"
26-
#include "reachability_slicer_class.h"
28+
#include "reachability_slicer.h"
29+
30+
void reachability_slicert::operator()(
31+
goto_functionst &goto_functions,
32+
const slicing_criteriont &criterion,
33+
bool include_forward_reachability,
34+
message_handlert &message_handler)
35+
{
36+
// Replace function calls without body by non-deterministic return values to
37+
// ensure the CFG does not consider instructions after such a call to be
38+
// unreachable.
39+
remove_calls_no_bodyt remove_calls_no_body;
40+
remove_calls_no_body(goto_functions, message_handler);
41+
goto_functions.update();
42+
43+
cfg(goto_functions);
44+
for(const auto &gf_entry : goto_functions.function_map)
45+
{
46+
forall_goto_program_instructions(i_it, gf_entry.second.body)
47+
cfg[cfg.entry_map[i_it]].function_id = gf_entry.first;
48+
}
49+
50+
is_threadedt is_threaded(goto_functions);
51+
fixedpoint_to_assertions(is_threaded, criterion);
52+
if(include_forward_reachability)
53+
fixedpoint_from_assertions(is_threaded, criterion);
54+
slice(goto_functions);
55+
}
2756

2857
/// Get the set of nodes that correspond to the given criterion, or that can
2958
/// appear in concurrent execution. None of these should be sliced away so
@@ -364,13 +393,18 @@ void reachability_slicert::slice(goto_functionst &goto_functions)
364393
/// \param include_forward_reachability: Determines if only instructions
365394
/// from which the criterion is reachable should be kept (false) or also
366395
/// those reachable from the criterion (true)
396+
/// \param message_handler: message handler
367397
void reachability_slicer(
368398
goto_modelt &goto_model,
369-
const bool include_forward_reachability)
399+
const bool include_forward_reachability,
400+
message_handlert &message_handler)
370401
{
371402
reachability_slicert s;
372403
assert_criteriont a;
373-
s(goto_model.goto_functions, a, include_forward_reachability);
404+
s(goto_model.goto_functions,
405+
a,
406+
include_forward_reachability,
407+
message_handler);
374408
}
375409

376410
/// Perform reachability slicing on goto_model for selected properties.
@@ -380,34 +414,42 @@ void reachability_slicer(
380414
/// \param include_forward_reachability: Determines if only instructions
381415
/// from which the criterion is reachable should be kept (false) or also
382416
/// those reachable from the criterion (true)
417+
/// \param message_handler: message handler
383418
void reachability_slicer(
384419
goto_modelt &goto_model,
385420
const std::list<std::string> &properties,
386-
const bool include_forward_reachability)
421+
const bool include_forward_reachability,
422+
message_handlert &message_handler)
387423
{
388424
reachability_slicert s;
389425
properties_criteriont p(properties);
390-
s(goto_model.goto_functions, p, include_forward_reachability);
426+
s(goto_model.goto_functions,
427+
p,
428+
include_forward_reachability,
429+
message_handler);
391430
}
392431

393432
/// Perform reachability slicing on goto_model for selected functions.
394433
/// \param goto_model: Goto program to slice
395434
/// \param functions_list: The functions relevant for the slicing (i.e. starting
396435
/// point for the search in the CFG). Anything that is reachable in the CFG
397436
/// starting from these functions will be kept.
437+
/// \param message_handler: message handler
398438
void function_path_reachability_slicer(
399439
goto_modelt &goto_model,
400-
const std::list<std::string> &functions_list)
440+
const std::list<std::string> &functions_list,
441+
message_handlert &message_handler)
401442
{
402443
for(const auto &function : functions_list)
403444
{
404445
in_function_criteriont matching_criterion(function);
405446
reachability_slicert slicer;
406-
slicer(goto_model.goto_functions, matching_criterion, true);
447+
slicer(
448+
goto_model.goto_functions, matching_criterion, true, message_handler);
407449
}
408450

409451
remove_calls_no_bodyt remove_calls_no_body;
410-
remove_calls_no_body(goto_model.goto_functions);
452+
remove_calls_no_body(goto_model.goto_functions, message_handler);
411453

412454
goto_model.goto_functions.update();
413455
goto_model.goto_functions.compute_loop_numbers();
@@ -417,19 +459,24 @@ void function_path_reachability_slicer(
417459
/// comprising all properties. Only instructions from which the criterion
418460
/// is reachable will be kept.
419461
/// \param goto_model: Goto program to slice
420-
void reachability_slicer(goto_modelt &goto_model)
462+
/// \param message_handler: message handler
463+
void reachability_slicer(
464+
goto_modelt &goto_model,
465+
message_handlert &message_handler)
421466
{
422-
reachability_slicer(goto_model, false);
467+
reachability_slicer(goto_model, false, message_handler);
423468
}
424469

425470
/// Perform reachability slicing on goto_model for selected properties. Only
426471
/// instructions from which the criterion is reachable will be kept.
427472
/// \param goto_model: Goto program to slice
428473
/// \param properties: The properties relevant for the slicing (i.e. starting
429474
/// point for the search in the cfg)
475+
/// \param message_handler: message handler
430476
void reachability_slicer(
431477
goto_modelt &goto_model,
432-
const std::list<std::string> &properties)
478+
const std::list<std::string> &properties,
479+
message_handlert &message_handler)
433480
{
434-
reachability_slicer(goto_model, properties, false);
481+
reachability_slicer(goto_model, properties, false, message_handler);
435482
}

src/goto-instrument/reachability_slicer.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,30 @@ Author: Daniel Kroening, [email protected]
1616
#include <string>
1717

1818
class goto_modelt;
19+
class message_handlert;
1920

20-
void reachability_slicer(goto_modelt &);
21+
void reachability_slicer(goto_modelt &, message_handlert &);
2122

2223
void reachability_slicer(
2324
goto_modelt &,
24-
const std::list<std::string> &properties);
25+
const std::list<std::string> &properties,
26+
message_handlert &);
2527

2628
void function_path_reachability_slicer(
2729
goto_modelt &goto_model,
28-
const std::list<std::string> &functions_list);
30+
const std::list<std::string> &functions_list,
31+
message_handlert &);
2932

3033
void reachability_slicer(
3134
goto_modelt &,
32-
const bool include_forward_reachability);
35+
const bool include_forward_reachability,
36+
message_handlert &);
3337

3438
void reachability_slicer(
3539
goto_modelt &,
3640
const std::list<std::string> &properties,
37-
const bool include_forward_reachability);
41+
const bool include_forward_reachability,
42+
message_handlert &);
3843

3944
// clang-format off
4045
#define OPT_REACHABILITY_SLICER \

src/goto-instrument/reachability_slicer_class.h

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,10 @@ Author: Daniel Kroening, [email protected]
1212
#ifndef CPROVER_GOTO_INSTRUMENT_REACHABILITY_SLICER_CLASS_H
1313
#define CPROVER_GOTO_INSTRUMENT_REACHABILITY_SLICER_CLASS_H
1414

15-
#include <goto-programs/goto_functions.h>
16-
#include <goto-programs/cfg.h>
17-
18-
#include <analyses/is_threaded.h>
15+
#include <goto-programs/goto_program.h>
1916

17+
class goto_functionst;
18+
class message_handlert;
2019
class slicing_criteriont;
2120

2221
class reachability_slicert
@@ -25,21 +24,8 @@ class reachability_slicert
2524
void operator()(
2625
goto_functionst &goto_functions,
2726
const slicing_criteriont &criterion,
28-
bool include_forward_reachability)
29-
{
30-
cfg(goto_functions);
31-
for(const auto &gf_entry : goto_functions.function_map)
32-
{
33-
forall_goto_program_instructions(i_it, gf_entry.second.body)
34-
cfg[cfg.entry_map[i_it]].function_id = gf_entry.first;
35-
}
36-
37-
is_threadedt is_threaded(goto_functions);
38-
fixedpoint_to_assertions(is_threaded, criterion);
39-
if(include_forward_reachability)
40-
fixedpoint_from_assertions(is_threaded, criterion);
41-
slice(goto_functions);
42-
}
27+
bool include_forward_reachability,
28+
message_handlert &);
4329

4430
protected:
4531
struct slicer_entryt

0 commit comments

Comments
 (0)