Skip to content

Commit d37341e

Browse files
authored
Merge pull request #2932 from danpoe/refactor/error-handling-solvers-flattening-from-boolbv-constant
Error handling cleanup in solvers/flattening 2
2 parents 3705a60 + ce19636 commit d37341e

File tree

3 files changed

+31
-65
lines changed

3 files changed

+31
-65
lines changed

src/ansi-c/c_typecheck_expr.cpp

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2732,26 +2732,6 @@ exprt c_typecheck_baset::do_special_functions(
27322732

27332733
return tmp;
27342734
}
2735-
else if(identifier==CPROVER_PREFIX "float_debug1" ||
2736-
identifier==CPROVER_PREFIX "float_debug2")
2737-
{
2738-
if(expr.arguments().size()!=2)
2739-
{
2740-
err_location(f_op);
2741-
error() << "float_debug expects two operands" << eom;
2742-
throw 0;
2743-
}
2744-
2745-
const irep_idt &id=
2746-
identifier==CPROVER_PREFIX "float_debug1"?
2747-
"float_debug1":"float_debug2";
2748-
2749-
exprt float_debug_expr(id, expr.type());
2750-
float_debug_expr.operands()=expr.arguments();
2751-
float_debug_expr.add_source_location()=source_location;
2752-
2753-
return float_debug_expr;
2754-
}
27552735
else if(identifier=="__sync_fetch_and_add" ||
27562736
identifier=="__sync_fetch_and_sub" ||
27572737
identifier=="__sync_fetch_and_or" ||

src/solvers/flattening/boolbv.cpp

Lines changed: 31 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Author: Daniel Kroening, [email protected]
88

99
#include "boolbv.h"
1010

11-
#include <cassert>
11+
#include <algorithm>
1212
#include <map>
1313
#include <set>
1414

@@ -36,7 +36,10 @@ bool boolbvt::literal(
3636
{
3737
if(expr.type().id()==ID_bool)
3838
{
39-
assert(bit==0);
39+
INVARIANT(
40+
bit == 0,
41+
"boolean expressions shall be represented by a single bit and hence the "
42+
"only valid bit index is 0");
4043
return prop_conv_solvert::literal(to_symbol_expr(expr), dest);
4144
}
4245
else
@@ -54,7 +57,8 @@ bool boolbvt::literal(
5457

5558
const boolbv_mapt::map_entryt &map_entry=it_m->second;
5659

57-
assert(bit<map_entry.literal_map.size());
60+
INVARIANT(
61+
bit < map_entry.literal_map.size(), "bit index shall be within bounds");
5862
if(!map_entry.literal_map[bit].is_set)
5963
return true;
6064

@@ -66,15 +70,11 @@ bool boolbvt::literal(
6670
const index_exprt &index_expr=to_index_expr(expr);
6771

6872
std::size_t element_width=boolbv_width(index_expr.type());
73+
CHECK_RETURN(element_width != 0);
6974

70-
if(element_width==0)
71-
throw "literal expects a bit-vector type";
75+
mp_integer index = numeric_cast_v<mp_integer>(index_expr.index());
7276

73-
mp_integer index;
74-
if(to_integer(index_expr.index(), index))
75-
throw "literal expects constant index";
76-
77-
std::size_t offset=integer2unsigned(index*element_width);
77+
std::size_t offset = numeric_cast_v<std::size_t>(index * element_width);
7878

7979
return literal(index_expr.array(), bit+offset, dest);
8080
}
@@ -96,18 +96,16 @@ bool boolbvt::literal(
9696
return literal(expr.op0(), bit+offset, dest);
9797

9898
std::size_t element_width=boolbv_width(subtype);
99-
100-
if(element_width==0)
101-
throw "literal expects a bit-vector type";
99+
CHECK_RETURN(element_width != 0);
102100

103101
offset+=element_width;
104102
}
105103

106-
throw "failed to find component";
104+
INVARIANT(false, "struct type should have accessed component");
107105
}
108106
}
109107

110-
throw "found no literal for expression";
108+
INVARIANT(false, "expression should have a corresponding literal");
111109
}
112110

113111
const bvt &
@@ -304,18 +302,6 @@ bvt boolbvt::convert_bitvector(const exprt &expr)
304302
return convert_not(to_not_expr(expr));
305303
else if(expr.id()==ID_power)
306304
return convert_power(to_binary_expr(expr));
307-
else if(expr.id()==ID_float_debug1 ||
308-
expr.id()==ID_float_debug2)
309-
{
310-
assert(expr.operands().size()==2);
311-
bvt bv0=convert_bitvector(expr.op0());
312-
bvt bv1=convert_bitvector(expr.op1());
313-
float_utilst float_utils(prop, to_floatbv_type(expr.type()));
314-
bvt bv=expr.id()==ID_float_debug1?
315-
float_utils.debug1(bv0, bv1):
316-
float_utils.debug2(bv0, bv1);
317-
return bv;
318-
}
319305
else if(expr.id() == ID_popcount)
320306
return convert_bv(lower_popcount(to_popcount_expr(expr), ns));
321307

@@ -329,8 +315,8 @@ bvt boolbvt::convert_lambda(const exprt &expr)
329315
if(width==0)
330316
return conversion_failed(expr);
331317

332-
if(expr.operands().size()!=2)
333-
throw "lambda takes two operands";
318+
DATA_INVARIANT(
319+
expr.operands().size() == 2, "lambda expression should have two operands");
334320

335321
if(expr.type().id()!=ID_array)
336322
return conversion_failed(expr);
@@ -357,10 +343,12 @@ bvt boolbvt::convert_lambda(const exprt &expr)
357343

358344
const bvt &tmp=convert_bv(expr_op1);
359345

360-
std::size_t offset=integer2unsigned(i*tmp.size());
346+
INVARIANT(
347+
size * tmp.size() == width,
348+
"total bitvector width shall equal the number of operands times the size "
349+
"per operand");
361350

362-
if(size*tmp.size()!=width)
363-
throw "convert_lambda: unexpected operand width";
351+
std::size_t offset = numeric_cast_v<std::size_t>(i * tmp.size());
364352

365353
for(std::size_t j=0; j<tmp.size(); j++)
366354
bv[offset+j]=tmp[j];
@@ -398,10 +386,8 @@ bvt boolbvt::convert_symbol(const exprt &expr)
398386
bvt bv;
399387
bv.resize(width);
400388

401-
const irep_idt &identifier=expr.get(ID_identifier);
402-
403-
if(identifier.empty())
404-
throw "convert_symbol got empty identifier";
389+
const irep_idt &identifier = expr.get(ID_identifier);
390+
CHECK_RETURN(!identifier.empty());
405391

406392
if(width==0)
407393
{
@@ -412,13 +398,15 @@ bvt boolbvt::convert_symbol(const exprt &expr)
412398
{
413399
map.get_literals(identifier, type, width, bv);
414400

415-
forall_literals(it, bv)
416-
if(it->var_no()>=prop.no_variables() &&
417-
!it->is_constant())
418-
{
419-
error() << identifier << eom;
420-
assert(false);
421-
}
401+
INVARIANT_WITH_DIAGNOSTICS(
402+
std::all_of(
403+
bv.begin(),
404+
bv.end(),
405+
[this](const literalt &l) {
406+
return l.var_no() < prop.no_variables() || l.is_constant();
407+
}),
408+
"variable number of non-constant literals should be within bounds",
409+
id2string(identifier));
422410
}
423411

424412
return bv;

src/util/irep_ids.def

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -515,8 +515,6 @@ IREP_ID_ONE(ptr_object)
515515
IREP_ID_TWO(C_c_sizeof_type, #c_sizeof_type)
516516
IREP_ID_ONE(array_update)
517517
IREP_ID_ONE(update)
518-
IREP_ID_ONE(float_debug1)
519-
IREP_ID_ONE(float_debug2)
520518
IREP_ID_ONE(static_assert)
521519
IREP_ID_ONE(gcc_attribute_mode)
522520
IREP_ID_TWO(built_in, <built-in>)

0 commit comments

Comments
 (0)