Skip to content

Commit 7f07693

Browse files
author
Daniel Kroening
authored
Merge pull request #5186 from diffblue/multi-unwindset
multiple --unwindset options
2 parents dd282e3 + 42a3ed2 commit 7f07693

File tree

6 files changed

+57
-39
lines changed

6 files changed

+57
-39
lines changed

doc/cprover-manual/cbmc-unwinding.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,14 @@ first use:
9090
to obtain a list of all loops in the program. Then identify the loops
9191
you need to set a separate bound for, and note their loop ID. Then use:
9292

93-
--unwindset L:B,L:B,...
93+
--unwindset L:B
9494

95-
where `L` denotes a loop ID and `B` denotes the bound for that loop.
95+
where `L` denotes a loop ID and `B` denotes the bound for that loop. The
96+
option can be given multiple times.
9697

9798
As an example, consider a program with two loops in the function main:
9899

99-
--unwindset c::main.0:10,c::main.1:20
100+
--unwindset main.0:10 --unwindset main.1:20
100101

101102
This sets a bound of 10 for the first loop, and a bound of 20 for the
102103
second loop.

src/cbmc/cbmc_parse_options.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ void cbmc_parse_optionst::get_command_line_options(optionst &options)
287287
}
288288

289289
if(cmdline.isset("unwindset"))
290-
options.set_option("unwindset", cmdline.get_value("unwindset"));
290+
options.set_option("unwindset", cmdline.get_values("unwindset"));
291291

292292
// constant propagation
293293
if(cmdline.isset("no-propagation"))

src/goto-checker/bmc_util.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ void setup_symex(
192192
symex.last_source_location.make_nil();
193193

194194
symex.unwindset.parse_unwind(options.get_option("unwind"));
195-
symex.unwindset.parse_unwindset(options.get_option("unwindset"));
195+
symex.unwindset.parse_unwindset(options.get_list_option("unwindset"));
196196
}
197197

198198
void slice(

src/goto-instrument/goto_instrument_parse_options.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ int goto_instrument_parse_optionst::doit()
175175
unwindset.parse_unwindset_file(cmdline.get_value("unwindset-file"));
176176

177177
if(unwindset_given)
178-
unwindset.parse_unwindset(cmdline.get_value("unwindset"));
178+
unwindset.parse_unwindset(cmdline.get_values("unwindset"));
179179

180180
bool unwinding_assertions=cmdline.isset("unwinding-assertions");
181181
bool partial_loops=cmdline.isset("partial-loops");

src/goto-instrument/unwindset.cpp

Lines changed: 42 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -21,43 +21,52 @@ void unwindsett::parse_unwind(const std::string &unwind)
2121
global_limit = unsafe_string2unsigned(unwind);
2222
}
2323

24-
void unwindsett::parse_unwindset(const std::string &unwindset)
24+
void unwindsett::parse_unwindset_one_loop(std::string val)
2525
{
26-
std::vector<std::string> unwindset_loops =
27-
split_string(unwindset, ',', true, true);
26+
unsigned thread_nr = 0;
27+
bool thread_nr_set = false;
2828

29-
for(auto &val : unwindset_loops)
29+
if(!val.empty() && isdigit(val[0]) && val.find(":") != std::string::npos)
3030
{
31-
unsigned thread_nr = 0;
32-
bool thread_nr_set = false;
33-
34-
if(!val.empty() && isdigit(val[0]) && val.find(":") != std::string::npos)
35-
{
36-
std::string nr = val.substr(0, val.find(":"));
37-
thread_nr = unsafe_string2unsigned(nr);
38-
thread_nr_set = true;
39-
val.erase(0, nr.size() + 1);
40-
}
41-
42-
if(val.rfind(":") != std::string::npos)
43-
{
44-
std::string id = val.substr(0, val.rfind(":"));
45-
std::string uw_string = val.substr(val.rfind(":") + 1);
46-
47-
// the below initialisation makes g++-5 happy
48-
optionalt<unsigned> uw(0);
49-
50-
if(uw_string.empty())
51-
uw = { };
52-
else
53-
uw = unsafe_string2unsigned(uw_string);
54-
55-
if(thread_nr_set)
56-
thread_loop_map[std::pair<irep_idt, unsigned>(id, thread_nr)] = uw;
57-
else
58-
loop_map[id] = uw;
59-
}
31+
std::string nr = val.substr(0, val.find(":"));
32+
thread_nr = unsafe_string2unsigned(nr);
33+
thread_nr_set = true;
34+
val.erase(0, nr.size() + 1);
6035
}
36+
37+
if(val.rfind(":") != std::string::npos)
38+
{
39+
std::string id = val.substr(0, val.rfind(":"));
40+
std::string uw_string = val.substr(val.rfind(":") + 1);
41+
42+
// the below initialisation makes g++-5 happy
43+
optionalt<unsigned> uw(0);
44+
45+
if(uw_string.empty())
46+
uw = {};
47+
else
48+
uw = unsafe_string2unsigned(uw_string);
49+
50+
if(thread_nr_set)
51+
thread_loop_map[std::pair<irep_idt, unsigned>(id, thread_nr)] = uw;
52+
else
53+
loop_map[id] = uw;
54+
}
55+
}
56+
57+
void unwindsett::parse_unwindset(const std::string &unwindset)
58+
{
59+
std::vector<std::string> unwindset_elements =
60+
split_string(unwindset, ',', true, true);
61+
62+
for(auto &element : unwindset_elements)
63+
parse_unwindset_one_loop(element);
64+
}
65+
66+
void unwindsett::parse_unwindset(const std::list<std::string> &unwindset)
67+
{
68+
for(auto &element : unwindset)
69+
parse_unwindset(element);
6170
}
6271

6372
optionalt<unsigned>

src/goto-instrument/unwindset.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ Author: Daniel Kroening, [email protected]
1212
#ifndef CPROVER_GOTO_INSTRUMENT_UNWINDSET_H
1313
#define CPROVER_GOTO_INSTRUMENT_UNWINDSET_H
1414

15+
#include <list>
1516
#include <map>
1617
#include <string>
1718

19+
#include <util/deprecate.h>
1820
#include <util/irep.h>
1921
#include <util/optional.h>
2022

@@ -31,8 +33,12 @@ class unwindsett
3133
void parse_unwind(const std::string &unwind);
3234

3335
// limit for instances of a loop
36+
DEPRECATED(SINCE(2019, 11, 15, "use parse_unwindset(list) instead"))
3437
void parse_unwindset(const std::string &unwindset);
3538

39+
// limit for instances of a loop
40+
void parse_unwindset(const std::list<std::string> &unwindset);
41+
3642
// queries
3743
optionalt<unsigned> get_limit(const irep_idt &loop, unsigned thread_id) const;
3844

@@ -51,6 +57,8 @@ class unwindsett
5157
using thread_loop_mapt =
5258
std::map<std::pair<irep_idt, unsigned>, optionalt<unsigned>>;
5359
thread_loop_mapt thread_loop_map;
60+
61+
void parse_unwindset_one_loop(std::string loop_limit);
5462
};
5563

5664
#endif // CPROVER_GOTO_INSTRUMENT_UNWINDSET_H

0 commit comments

Comments
 (0)