Skip to content

Commit 514a0a5

Browse files
author
Daniel Kroening
authored
Merge pull request diffblue#2167 from diffblue/parse_unwindset_options
move setup_unwind to parse_unwindset_options to prevent duplication
2 parents a06503b + f1b6174 commit 514a0a5

File tree

13 files changed

+209
-258
lines changed

13 files changed

+209
-258
lines changed

regression/goto-instrument/unwind-unwindset3/test.desc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CORE
22
main.c
3-
--unwind 10 --unwindset main.0:-1
3+
--unwind 10 --unwindset main.0:
44
^Unwinding loop
55
^EXIT=0$
66
^SIGNAL=0$

src/cbmc/Makefile

+4-3
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,6 @@ OBJ += ../ansi-c/ansi-c$(LIBEXT) \
3030
../pointer-analysis/add_failed_symbols$(OBJEXT) \
3131
../pointer-analysis/rewrite_index$(OBJEXT) \
3232
../pointer-analysis/goto_program_dereference$(OBJEXT) \
33-
../goto-instrument/reachability_slicer$(OBJEXT) \
34-
../goto-instrument/full_slicer$(OBJEXT) \
35-
../goto-instrument/nondet_static$(OBJEXT) \
3633
../goto-instrument/cover$(OBJEXT) \
3734
../goto-instrument/cover_basic_blocks$(OBJEXT) \
3835
../goto-instrument/cover_filter$(OBJEXT) \
@@ -43,6 +40,10 @@ OBJ += ../ansi-c/ansi-c$(LIBEXT) \
4340
../goto-instrument/cover_instrument_mcdc$(OBJEXT) \
4441
../goto-instrument/cover_instrument_other$(OBJEXT) \
4542
../goto-instrument/cover_util$(OBJEXT) \
43+
../goto-instrument/reachability_slicer$(OBJEXT) \
44+
../goto-instrument/nondet_static$(OBJEXT) \
45+
../goto-instrument/full_slicer$(OBJEXT) \
46+
../goto-instrument/unwindset$(OBJEXT) \
4647
../analyses/analyses$(LIBEXT) \
4748
../langapi/langapi$(LIBEXT) \
4849
../xmllang/xmllang$(LIBEXT) \

src/cbmc/bmc.cpp

+2-40
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ Author: Daniel Kroening, [email protected]
1515
#include <iostream>
1616

1717
#include <util/exit_codes.h>
18-
#include <util/string2int.h>
19-
#include <util/string_utils.h>
2018

2119
#include <langapi/language_util.h>
2220

@@ -319,7 +317,8 @@ void bmct::setup()
319317

320318
symex.last_source_location.make_nil();
321319

322-
setup_unwind();
320+
symex.unwindset.parse_unwind(options.get_option("unwind"));
321+
symex.unwindset.parse_unwindset(options.get_option("unwindset"));
323322
}
324323

325324
safety_checkert::resultt bmct::execute(
@@ -549,43 +548,6 @@ safety_checkert::resultt bmct::stop_on_fail(prop_convt &prop_conv)
549548
}
550549
}
551550

552-
void bmct::setup_unwind()
553-
{
554-
const std::string &set=options.get_option("unwindset");
555-
std::vector<std::string> unwindset_loops;
556-
split_string(set, ',', unwindset_loops, true, true);
557-
558-
for(auto &val : unwindset_loops)
559-
{
560-
unsigned thread_nr=0;
561-
bool thread_nr_set=false;
562-
563-
if(!val.empty() &&
564-
isdigit(val[0]) &&
565-
val.find(":")!=std::string::npos)
566-
{
567-
std::string nr=val.substr(0, val.find(":"));
568-
thread_nr=unsafe_string2unsigned(nr);
569-
thread_nr_set=true;
570-
val.erase(0, nr.size()+1);
571-
}
572-
573-
if(val.rfind(":")!=std::string::npos)
574-
{
575-
std::string id=val.substr(0, val.rfind(":"));
576-
long uw=unsafe_string2int(val.substr(val.rfind(":")+1));
577-
578-
if(thread_nr_set)
579-
symex.set_unwind_thread_loop_limit(thread_nr, id, uw);
580-
else
581-
symex.set_unwind_loop_limit(id, uw);
582-
}
583-
}
584-
585-
if(options.get_option("unwind")!="")
586-
symex.set_unwind_limit(options.get_unsigned_int_option("unwind"));
587-
}
588-
589551
/// Perform core BMC, using an abstract model to supply GOTO function bodies
590552
/// (perhaps created on demand).
591553
/// \param opts: command-line options affecting BMC

src/cbmc/bmc.h

-2
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,6 @@ class bmct:public safety_checkert
183183
const goto_functionst &,
184184
prop_convt &);
185185

186-
// unwinding
187-
virtual void setup_unwind();
188186
void do_conversion();
189187

190188
virtual void freeze_program_variables();

src/cbmc/symex_bmc.cpp

+8-36
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ symex_bmct::symex_bmct(
2525
path_storaget &path_storage)
2626
: goto_symext(mh, outer_symbol_table, _target, path_storage),
2727
record_coverage(false),
28-
max_unwind(0),
29-
max_unwind_is_set(false),
3028
symex_coverage(ns)
3129
{
3230
}
@@ -131,25 +129,12 @@ bool symex_bmct::get_unwind(
131129
// / --unwind options to decide:
132130
if(abort_unwind_decision.is_unknown())
133131
{
134-
// We use the most specific limit we have,
135-
// and 'infinity' when we have none.
132+
auto limit=unwindset.get_limit(id, source.thread_nr);
136133

137-
loop_limitst &this_thread_limits=
138-
thread_loop_limits[source.thread_nr];
139-
140-
loop_limitst::const_iterator l_it=this_thread_limits.find(id);
141-
if(l_it!=this_thread_limits.end())
142-
this_loop_limit=l_it->second;
134+
if(!limit.has_value())
135+
abort_unwind_decision = tvt(false);
143136
else
144-
{
145-
l_it=loop_limits.find(id);
146-
if(l_it!=loop_limits.end())
147-
this_loop_limit=l_it->second;
148-
else if(max_unwind_is_set)
149-
this_loop_limit=max_unwind;
150-
}
151-
152-
abort_unwind_decision = tvt(unwind >= this_loop_limit);
137+
abort_unwind_decision = tvt(unwind >= *limit);
153138
}
154139

155140
INVARIANT(
@@ -187,25 +172,12 @@ bool symex_bmct::get_unwind_recursion(
187172
// / --unwind options to decide:
188173
if(abort_unwind_decision.is_unknown())
189174
{
190-
// We use the most specific limit we have,
191-
// and 'infinity' when we have none.
192-
193-
loop_limitst &this_thread_limits=
194-
thread_loop_limits[thread_nr];
175+
auto limit=unwindset.get_limit(id, thread_nr);
195176

196-
loop_limitst::const_iterator l_it=this_thread_limits.find(id);
197-
if(l_it!=this_thread_limits.end())
198-
this_loop_limit=l_it->second;
177+
if(!limit.has_value())
178+
abort_unwind_decision = tvt(false);
199179
else
200-
{
201-
l_it=loop_limits.find(id);
202-
if(l_it!=loop_limits.end())
203-
this_loop_limit=l_it->second;
204-
else if(max_unwind_is_set)
205-
this_loop_limit=max_unwind;
206-
}
207-
208-
abort_unwind_decision = tvt(unwind>this_loop_limit);
180+
abort_unwind_decision = tvt(unwind > *limit);
209181
}
210182

211183
INVARIANT(

src/cbmc/symex_bmc.h

+5-40
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ Author: Daniel Kroening, [email protected]
1818
#include <goto-symex/path_storage.h>
1919
#include <goto-symex/goto_symex.h>
2020

21+
#include <goto-instrument/unwindset.h>
22+
2123
#include "symex_coverage.h"
2224

2325
class symex_bmct: public goto_symext
@@ -32,29 +34,6 @@ class symex_bmct: public goto_symext
3234
// To show progress
3335
source_locationt last_source_location;
3436

35-
// Control unwinding.
36-
37-
void set_unwind_limit(unsigned limit)
38-
{
39-
max_unwind=limit;
40-
max_unwind_is_set=true;
41-
}
42-
43-
void set_unwind_thread_loop_limit(
44-
unsigned thread_nr,
45-
const irep_idt &id,
46-
unsigned limit)
47-
{
48-
thread_loop_limits[thread_nr][id]=limit;
49-
}
50-
51-
void set_unwind_loop_limit(
52-
const irep_idt &id,
53-
unsigned limit)
54-
{
55-
loop_limits[id]=limit;
56-
}
57-
5837
/// Loop unwind handlers take the function ID and loop number, the unwind
5938
/// count so far, and an out-parameter specifying an advisory maximum, which
6039
/// they may set. If set the advisory maximum is set it is *only* used to
@@ -101,26 +80,12 @@ class symex_bmct: public goto_symext
10180

10281
bool record_coverage;
10382

104-
protected:
105-
// We have
106-
// 1) a global limit (max_unwind)
107-
// 2) a limit per loop, all threads
108-
// 3) a limit for a particular thread.
109-
// 4) zero or more handler functions that can special-case particular
110-
// functions or loops
111-
// We use the most specific of the above.
112-
113-
unsigned max_unwind;
114-
bool max_unwind_is_set;
115-
116-
typedef std::unordered_map<irep_idt, unsigned> loop_limitst;
117-
loop_limitst loop_limits;
118-
119-
typedef std::map<unsigned, loop_limitst> thread_loop_limitst;
120-
thread_loop_limitst thread_loop_limits;
83+
unwindsett unwindset;
12184

85+
protected:
12286
/// Callbacks that may provide an unwind/do-not-unwind decision for a loop
12387
std::vector<loop_unwind_handlert> loop_unwind_handlers;
88+
12489
/// Callbacks that may provide an unwind/do-not-unwind decision for a
12590
/// recursive call
12691
std::vector<recursion_unwind_handlert> recursion_unwind_handlers;

src/goto-instrument/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ SRC = accelerate/accelerate.cpp \
6161
undefined_functions.cpp \
6262
uninitialized.cpp \
6363
unwind.cpp \
64+
unwindset.cpp \
6465
wmm/abstract_event.cpp \
6566
wmm/cycle_collection.cpp \
6667
wmm/data_dp.cpp \

src/goto-instrument/goto_instrument_parse_options.cpp

+13-30
Original file line numberDiff line numberDiff line change
@@ -139,43 +139,26 @@ int goto_instrument_parse_optionst::doit()
139139
instrument_goto_program();
140140

141141
{
142-
bool unwind=cmdline.isset("unwind");
143-
bool unwindset=cmdline.isset("unwindset");
144-
bool unwindset_file=cmdline.isset("unwindset-file");
142+
bool unwind_given=cmdline.isset("unwind");
143+
bool unwindset_given=cmdline.isset("unwindset");
144+
bool unwindset_file_given=cmdline.isset("unwindset-file");
145145

146-
if(unwindset && unwindset_file)
146+
if(unwindset_given && unwindset_file_given)
147147
throw "only one of --unwindset and --unwindset-file supported at a "
148148
"time";
149149

150-
if(unwind || unwindset || unwindset_file)
150+
if(unwind_given || unwindset_given || unwindset_file_given)
151151
{
152-
int k=-1;
152+
unwindsett unwindset;
153153

154-
if(unwind)
155-
k=std::stoi(cmdline.get_value("unwind"));
154+
if(unwind_given)
155+
unwindset.parse_unwind(cmdline.get_value("unwind"));
156156

157-
unwind_sett unwind_set;
157+
if(unwindset_file_given)
158+
unwindset.parse_unwindset_file(cmdline.get_value("unwindset-file"));
158159

159-
if(unwindset_file)
160-
{
161-
std::string us;
162-
std::string fn=cmdline.get_value("unwindset-file");
163-
164-
#ifdef _MSC_VER
165-
std::ifstream file(widen(fn));
166-
#else
167-
std::ifstream file(fn);
168-
#endif
169-
if(!file)
170-
throw "cannot open file "+fn;
171-
172-
std::stringstream buffer;
173-
buffer << file.rdbuf();
174-
us=buffer.str();
175-
parse_unwindset(us, unwind_set);
176-
}
177-
else if(unwindset)
178-
parse_unwindset(cmdline.get_value("unwindset"), unwind_set);
160+
if(unwindset_given)
161+
unwindset.parse_unwindset(cmdline.get_value("unwindset"));
179162

180163
bool unwinding_assertions=cmdline.isset("unwinding-assertions");
181164
bool partial_loops=cmdline.isset("partial-loops");
@@ -202,7 +185,7 @@ int goto_instrument_parse_optionst::doit()
202185
}
203186

204187
goto_unwindt goto_unwind;
205-
goto_unwind(goto_model, unwind_set, k, unwind_strategy);
188+
goto_unwind(goto_model, unwindset, unwind_strategy);
206189

207190
goto_model.goto_functions.update();
208191
goto_model.goto_functions.compute_loop_numbers();

0 commit comments

Comments
 (0)