Skip to content

Commit b01d603

Browse files
authored
Merge pull request #2703 from NlightNFotis/develop_cbmc_cleanup_rebase
Cleanup error handling of cbmc/ folder
2 parents 0ec4e7d + 2e6d6a0 commit b01d603

11 files changed

+141
-42
lines changed

src/cbmc/bmc.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Author: Daniel Kroening, [email protected]
1414
#include <chrono>
1515
#include <iostream>
1616

17+
#include <util/exception_utils.h>
1718
#include <util/exit_codes.h>
1819

1920
#include <langapi/language_util.h>
@@ -214,9 +215,8 @@ void bmct::get_memory_model()
214215
memory_model=util_make_unique<memory_model_psot>(ns);
215216
else
216217
{
217-
error() << "Invalid memory model " << mm
218-
<< " -- use one of sc, tso, pso" << eom;
219-
throw "invalid memory model";
218+
throw invalid_user_input_exceptiont(
219+
"invalid parameter " + mm, "--mm", "try values of sc, tso, pso");
220220
}
221221
}
222222

src/cbmc/bmc_cover.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ bool bmc_covert::operator()()
219219
{
220220
if(it->is_assert())
221221
{
222-
assert(it->source.pc->is_assert());
222+
PRECONDITION(it->source.pc->is_assert());
223223
const and_exprt c(
224224
literal_exprt(it->guard_literal), literal_exprt(!it->cond_literal));
225225
literalt l_c=solver.convert(c);
@@ -239,7 +239,9 @@ bool bmc_covert::operator()()
239239
cover_goals.add(l);
240240
}
241241

242-
assert(cover_goals.size()==goal_map.size());
242+
INVARIANT(cover_goals.size() == goal_map.size(),
243+
"we add coverage for each goal");
244+
243245

244246
status() << "Running " << solver.decision_procedure_text() << eom;
245247

src/cbmc/cbmc_main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ int main(int argc, const char **argv)
4343
#endif
4444
cbmc_parse_optionst parse_options(argc, argv);
4545

46-
int res=parse_options.main();
46+
int res = parse_options.main();
4747

4848
#ifdef IREP_HASH_STATS
4949
std::cout << "IREP_HASH_CNT=" << irep_hash_cnt << '\n';

src/cbmc/cbmc_solvers.cpp

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ Author: Daniel Kroening, [email protected]
1414
#include <fstream>
1515
#include <iostream>
1616
#include <memory>
17+
#include <string>
1718

19+
#include <util/exception_utils.h>
1820
#include <util/make_unique.h>
1921
#include <util/unicode.h>
2022
#include <util/version.h>
@@ -32,7 +34,8 @@ Author: Daniel Kroening, [email protected]
3234
/// \return An smt2_dect::solvert giving the solver to use.
3335
smt2_dect::solvert cbmc_solverst::get_smt2_solver_type() const
3436
{
35-
assert(options.get_bool_option("smt2"));
37+
// we shouldn't get here if this option isn't set
38+
PRECONDITION(options.get_bool_option("smt2"));
3639

3740
smt2_dect::solvert s=smt2_dect::solvert::GENERIC;
3841

@@ -163,8 +166,10 @@ std::unique_ptr<cbmc_solverst::solvert> cbmc_solverst::get_smt2(
163166
{
164167
if(solver==smt2_dect::solvert::GENERIC)
165168
{
166-
error() << "please use --outfile" << eom;
167-
throw 0;
169+
throw invalid_user_input_exceptiont(
170+
"required filename not provided",
171+
"--outfile",
172+
"provide a filename with --outfile");
168173
}
169174

170175
auto smt2_dec = util_make_unique<smt2_dect>(
@@ -206,8 +211,8 @@ std::unique_ptr<cbmc_solverst::solvert> cbmc_solverst::get_smt2(
206211

207212
if(!*out)
208213
{
209-
error() << "failed to open " << filename << eom;
210-
throw 0;
214+
throw invalid_user_input_exceptiont(
215+
"failed to open file: " + filename, "--outfile");
211216
}
212217

213218
auto smt2_conv = util_make_unique<smt2_convt>(
@@ -231,18 +236,32 @@ void cbmc_solverst::no_beautification()
231236
{
232237
if(options.get_bool_option("beautify"))
233238
{
234-
error() << "sorry, this solver does not support beautification" << eom;
235-
throw 0;
239+
throw invalid_user_input_exceptiont(
240+
"the chosen solver does not support beautification", "--beautify");
236241
}
237242
}
238243

239244
void cbmc_solverst::no_incremental_check()
240245
{
241-
if(options.get_bool_option("all-properties") ||
242-
options.get_option("cover")!="" ||
243-
options.get_option("incremental-check")!="")
246+
const bool all_properties = options.get_bool_option("all-properties");
247+
const bool cover = options.is_set("cover");
248+
const bool incremental_check = options.is_set("incremental-check");
249+
250+
if(all_properties)
251+
{
252+
throw invalid_user_input_exceptiont(
253+
"the chosen solver does not support incremental solving",
254+
"--all_properties");
255+
}
256+
else if(cover)
257+
{
258+
throw invalid_user_input_exceptiont(
259+
"the chosen solver does not support incremental solving", "--cover");
260+
}
261+
else if(incremental_check)
244262
{
245-
error() << "sorry, this solver does not support incremental solving" << eom;
246-
throw 0;
263+
throw invalid_user_input_exceptiont(
264+
"the chosen solver does not support incremental solving",
265+
"--incremental-check");
247266
}
248267
}

src/cbmc/cbmc_solvers.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,13 @@ class cbmc_solverst:public messaget
6868

6969
prop_convt &prop_conv() const
7070
{
71-
assert(prop_conv_ptr!=nullptr);
71+
PRECONDITION(prop_conv_ptr != nullptr);
7272
return *prop_conv_ptr;
7373
}
7474

7575
propt &prop() const
7676
{
77-
assert(prop_ptr!=nullptr);
77+
PRECONDITION(prop_ptr != nullptr);
7878
return *prop_ptr;
7979
}
8080

src/cbmc/fault_localization.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ fault_localizationt::get_failed_property()
8181
bool fault_localizationt::check(const lpointst &lpoints,
8282
const lpoints_valuet &value)
8383
{
84-
assert(value.size()==lpoints.size());
84+
PRECONDITION(value.size() == lpoints.size());
8585
bvt assumptions;
8686
lpoints_valuet::const_iterator v_it=value.begin();
8787
for(const auto &l : lpoints)
@@ -142,7 +142,7 @@ void fault_localizationt::run(irep_idt goal_id)
142142
{
143143
// find failed property
144144
failed=get_failed_property();
145-
assert(failed!=bmc.equation.SSA_steps.end());
145+
PRECONDITION(failed != bmc.equation.SSA_steps.end());
146146

147147
if(goal_id==ID_nil)
148148
goal_id=failed->source.pc->source_location.get_property_id();

src/cbmc/symex_coverage.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -139,15 +139,17 @@ goto_program_coverage_recordt::goto_program_coverage_recordt(
139139
const symex_coveraget::coveraget &coverage):
140140
coverage_recordt("method")
141141
{
142-
assert(gf_it->second.body_available());
142+
PRECONDITION(gf_it->second.body_available());
143143

144144
// identify the file name, inlined functions aren't properly
145145
// accounted for
146146
goto_programt::const_targett end_function=
147147
--gf_it->second.body.instructions.end();
148-
assert(end_function->is_end_function());
148+
DATA_INVARIANT(
149+
end_function->is_end_function(),
150+
"last instruction in a function body is end function");
149151
file_name=end_function->source_location.get_file();
150-
assert(!file_name.empty());
152+
DATA_INVARIANT(!file_name.empty(), "should have a valid source location");
151153

152154
// compute the maximum coverage of individual source-code lines
153155
coverage_lines_mapt coverage_lines_map;
@@ -260,11 +262,15 @@ void goto_program_coverage_recordt::compute_coverage_lines(
260262
for(const auto &cov : c_entry->second)
261263
std::cerr << cov.second.succ->location_number << '\n';
262264
}
263-
assert(c_entry->second.size()==1 || is_branch);
265+
DATA_INVARIANT(
266+
c_entry->second.size() == 1 || is_branch,
267+
"instructions other than branch instructions have exactly 1 successor");
264268

265269
for(const auto &cov : c_entry->second)
266270
{
267-
assert(cov.second.num_executions>0);
271+
DATA_INVARIANT(
272+
cov.second.num_executions > 0,
273+
"coverage entries can only exist with at least one execution");
268274

269275
if(entry.first->second.hits==0)
270276
++lines_covered;
@@ -275,7 +281,9 @@ void goto_program_coverage_recordt::compute_coverage_lines(
275281
if(is_branch)
276282
{
277283
auto cond_entry=entry.first->second.conditions.find(it);
278-
assert(cond_entry!=entry.first->second.conditions.end());
284+
INVARIANT(
285+
cond_entry != entry.first->second.conditions.end(),
286+
"branch should have condition");
279287

280288
if(it->get_target()==cov.second.succ)
281289
{
@@ -439,7 +447,7 @@ bool symex_coveraget::generate_report(
439447
const goto_functionst &goto_functions,
440448
const std::string &path) const
441449
{
442-
assert(!path.empty());
450+
PRECONDITION(!path.empty());
443451

444452
if(path=="-")
445453
return output_report(goto_functions, std::cout);

src/util/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ SRC = arith_tools.cpp \
1313
expr.cpp \
1414
expr_initializer.cpp \
1515
expr_util.cpp \
16+
exception_utils.cpp \
1617
file_util.cpp \
1718
find_macros.cpp \
1819
find_symbols.cpp \

src/util/exception_utils.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*******************************************************************\
2+
3+
Module: Exception helper utilities
4+
5+
Author: Fotis Koutoulakis, [email protected]
6+
7+
\*******************************************************************/
8+
9+
#include "exception_utils.h"
10+
11+
std::string invalid_user_input_exceptiont::what() const noexcept
12+
{
13+
std::string res;
14+
res += "\nInvalid User Input\n";
15+
res += "Option: " + option + "\n";
16+
res += "Reason: " + reason;
17+
// Print an optional correct usage message assuming correct input parameters have been passed
18+
res += correct_input + "\n";
19+
return res;
20+
}

src/util/exception_utils.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*******************************************************************\
2+
3+
Module: Exception helper utilities
4+
5+
Author: Fotis Koutoulakis, [email protected]
6+
7+
\*******************************************************************/
8+
9+
#ifndef CPROVER_UTIL_EXCEPTION_UTILS_H
10+
#define CPROVER_UTIL_EXCEPTION_UTILS_H
11+
12+
#include <string>
13+
14+
class invalid_user_input_exceptiont
15+
{
16+
/// The reason this exception was generated.
17+
std::string reason;
18+
/// The full command line option (not the argument) that got
19+
/// erroneous input.
20+
std::string option;
21+
/// In case we have samples of correct input to the option.
22+
std::string correct_input;
23+
24+
public:
25+
invalid_user_input_exceptiont(
26+
std::string reason,
27+
std::string option,
28+
std::string correct_input = "")
29+
: reason(reason), option(option), correct_input(correct_input)
30+
{
31+
}
32+
33+
std::string what() const noexcept;
34+
};
35+
36+
#endif // CPROVER_UTIL_EXCEPTION_UTILS_H

src/util/parse_options.cpp

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ Author: Daniel Kroening, [email protected]
1818
#endif
1919

2020
#include "cmdline.h"
21+
#include "exception_utils.h"
22+
#include "exit_codes.h"
2123
#include "signal_catcher.h"
2224

2325
parse_options_baset::parse_options_baset(
@@ -47,23 +49,34 @@ void parse_options_baset::unknown_option_msg()
4749

4850
int parse_options_baset::main()
4951
{
50-
if(parse_result)
52+
// catch all exceptions here so that this code is not duplicated
53+
// for each tool
54+
try
5155
{
52-
usage_error();
53-
unknown_option_msg();
54-
return EX_USAGE;
56+
if(parse_result)
57+
{
58+
usage_error();
59+
unknown_option_msg();
60+
return EX_USAGE;
61+
}
62+
63+
if(cmdline.isset('?') || cmdline.isset('h') || cmdline.isset("help"))
64+
{
65+
help();
66+
return EX_OK;
67+
}
68+
69+
// install signal catcher
70+
install_signal_catcher();
71+
72+
return doit();
5573
}
56-
57-
if(cmdline.isset('?') || cmdline.isset('h') || cmdline.isset("help"))
74+
catch(invalid_user_input_exceptiont &e)
5875
{
59-
help();
60-
return EX_OK;
76+
std::cerr << e.what() << "\n";
77+
return CPROVER_EXIT_USAGE_ERROR;
6178
}
62-
63-
// install signal catcher
64-
install_signal_catcher();
65-
66-
return doit();
79+
return CPROVER_EXIT_SUCCESS;
6780
}
6881

6982
std::string

0 commit comments

Comments
 (0)