Skip to content

Commit 40b2355

Browse files
Petr BauchNlightNFotis
authored andcommitted
Substitute duplicate invariants with transfer function calls
Remove duplicate invariants, and change some to transfer (cast) function calls, which provide guarantees about the data types by construction. Also substitute invariants with exceptions where appropriate.
1 parent ccce5d7 commit 40b2355

File tree

3 files changed

+41
-43
lines changed

3 files changed

+41
-43
lines changed

src/cbmc/cbmc_parse_options.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Author: Daniel Kroening, [email protected]
1717
#include <memory>
1818

1919
#include <util/config.h>
20+
#include <util/exception_utils.h>
2021
#include <util/exit_codes.h>
2122
#include <util/invariant.h>
2223
#include <util/unicode.h>
@@ -611,6 +612,12 @@ int cbmc_parse_optionst::get_goto_program(
611612
log.status() << config.object_bits_info() << log.eom;
612613
}
613614

615+
catch(incorrect_goto_program_exceptiont &e)
616+
{
617+
log.error() << e.what() << log.eom;
618+
return CPROVER_EXIT_EXCEPTION;
619+
}
620+
614621
catch(const char *e)
615622
{
616623
log.error() << e << log.eom;

src/goto-programs/goto_convert.cpp

Lines changed: 31 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@ Author: Daniel Kroening, [email protected]
1111

1212
#include "goto_convert.h"
1313

14-
#include <cassert>
15-
1614
#include <util/arith_tools.h>
1715
#include <util/cprover_prefix.h>
16+
#include <util/exception_utils.h>
1817
#include <util/expr_util.h>
1918
#include <util/fresh_symbol.h>
2019
#include <util/prefix.h>
@@ -116,10 +115,12 @@ void goto_convertt::finish_gotos(goto_programt &dest, const irep_idt &mode)
116115
labelst::const_iterator l_it=
117116
targets.labels.find(goto_label);
118117

119-
DATA_INVARIANT(
120-
l_it != targets.labels.end(),
121-
i.code.find_source_location().as_string() + ": goto label '" +
122-
id2string(goto_label) + "' not found");
118+
if(l_it == targets.labels.end())
119+
{
120+
throw incorrect_goto_program_exceptiont(
121+
"goto label \'" + id2string(goto_label) + "\' not found",
122+
i.code.find_source_location());
123+
}
123124

124125
i.targets.push_back(l_it->second.first);
125126
}
@@ -129,10 +130,12 @@ void goto_convertt::finish_gotos(goto_programt &dest, const irep_idt &mode)
129130

130131
labelst::const_iterator l_it=targets.labels.find(goto_label);
131132

132-
DATA_INVARIANT(
133-
l_it != targets.labels.end(),
134-
i.code.find_source_location().as_string() + ": goto label '" +
135-
id2string(goto_label) + "' not found");
133+
if(l_it == targets.labels.end())
134+
{
135+
throw incorrect_goto_program_exceptiont(
136+
"goto label \'" + id2string(goto_label) + "\' not found",
137+
i.code.find_source_location());
138+
}
136139

137140
i.complete_goto(l_it->second.first);
138141

@@ -192,13 +195,8 @@ void goto_convertt::finish_computed_gotos(goto_programt &goto_program)
192195
for(auto &g_it : targets.computed_gotos)
193196
{
194197
goto_programt::instructiont &i=*g_it;
195-
exprt destination=i.code.op0();
196-
197-
DATA_INVARIANT(
198-
destination.id() == ID_dereference, "dereference ID not allowed here");
199-
DATA_INVARIANT(destination.operands().size() == 1, "expected 1 argument");
200-
201-
exprt pointer=destination.op0();
198+
dereference_exprt destination = to_dereference_expr(i.code.op0());
199+
exprt pointer = destination.op();
202200

203201
// remember the expression for later checks
204202
i.type=OTHER;
@@ -516,7 +514,7 @@ void goto_convertt::convert(
516514
assertion.make_typecast(bool_typet());
517515
simplify(assertion, ns);
518516
INVARIANT(
519-
assertion.is_false(),
517+
!assertion.is_false(),
520518
code.op0().find_source_location().as_string() + ": static assertion " +
521519
id2string(get_string_constant(code.op1())));
522520
}
@@ -580,12 +578,7 @@ void goto_convertt::convert_expression(
580578
goto_programt &dest,
581579
const irep_idt &mode)
582580
{
583-
INVARIANT(
584-
code.operands().size() == 1,
585-
code.find_source_location().as_string() +
586-
": expression statement takes one operand");
587-
588-
exprt expr=code.op0();
581+
exprt expr = code.expression();
589582

590583
if(expr.id()==ID_if)
591584
{
@@ -622,14 +615,7 @@ void goto_convertt::convert_decl(
622615
goto_programt &dest,
623616
const irep_idt &mode)
624617
{
625-
const exprt &op = code.symbol();
626-
627-
INVARIANT(
628-
op.id() == ID_symbol,
629-
op.find_source_location().as_string() +
630-
": decl statement expects symbol as operand");
631-
632-
const irep_idt &identifier = to_symbol_expr(op).get_identifier();
618+
const irep_idt &identifier = to_symbol_expr(code.symbol()).get_identifier();
633619

634620
const symbolt &symbol = ns.lookup(identifier);
635621

@@ -774,11 +760,8 @@ void goto_convertt::convert_assign(
774760

775761
if(lhs.id()==ID_typecast)
776762
{
777-
INVARIANT(lhs.operands().size() == 1, "typecast takes one operand");
778-
779763
// add a typecast to the rhs
780-
exprt new_rhs=rhs;
781-
rhs.make_typecast(lhs.op0().type());
764+
rhs.make_typecast(to_typecast_expr(lhs).op().type());
782765

783766
// remove typecast from lhs
784767
exprt tmp=lhs.op0();
@@ -1269,7 +1252,9 @@ void goto_convertt::convert_switch(
12691252
{
12701253
const caset &case_ops=case_pair.second;
12711254

1272-
assert(!case_ops.empty());
1255+
if(case_ops.empty())
1256+
throw incorrect_goto_program_exceptiont(
1257+
"switch case range cannot be empty", code.find_source_location());
12731258

12741259
exprt guard_expr=case_guard(argument, case_ops);
12751260

@@ -1325,9 +1310,8 @@ void goto_convertt::convert_return(
13251310
{
13261311
if(!targets.return_set)
13271312
{
1328-
error().source_location=code.find_source_location();
1329-
error() << "return without target" << eom;
1330-
throw 0;
1313+
throw incorrect_goto_program_exceptiont(
1314+
"return without target", code.find_source_location());
13311315
}
13321316

13331317
DATA_INVARIANT(
@@ -1763,10 +1747,14 @@ void goto_convertt::generate_conditional_branch(
17631747
{
17641748
if(guard.id()==ID_not)
17651749
{
1766-
PRECONDITION(guard.operands().size() == 1);
17671750
// simply swap targets
17681751
generate_conditional_branch(
1769-
guard.op0(), target_false, target_true, source_location, dest, mode);
1752+
to_not_expr(guard).op(),
1753+
target_false,
1754+
target_true,
1755+
source_location,
1756+
dest,
1757+
mode);
17701758
return;
17711759
}
17721760

@@ -1877,7 +1865,7 @@ irep_idt goto_convertt::get_string_constant(const exprt &expr)
18771865
irep_idt result;
18781866

18791867
bool res = get_string_constant(expr, result);
1880-
INVARIANT(
1868+
INVARIANT_WITH_DIAGNOSTICS(
18811869
!res,
18821870
expr.find_source_location().as_string() + ": expected string constant",
18831871
expr.pretty());

src/util/std_code.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,9 @@ inline const code_declt &to_code_decl(const codet &code)
315315
// will be size()==1 in the future
316316
DATA_INVARIANT(
317317
code.operands().size() >= 1, "decls must have one or more operands");
318+
DATA_INVARIANT(
319+
code.op0().id() == ID_symbol, "decls symbols must be a \"symbol\"");
320+
318321
return static_cast<const code_declt &>(code);
319322
}
320323

0 commit comments

Comments
 (0)