Skip to content

Commit d07bba7

Browse files
committed
Error handling cleanup in solvers/flattening
Files equality.cpp to pointer_logic.h
1 parent c89d376 commit d07bba7

File tree

4 files changed

+85
-84
lines changed

4 files changed

+85
-84
lines changed

src/solvers/flattening/equality.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,9 @@ literalt equalityt::equality(const exprt &e1, const exprt &e2)
2424

2525
literalt equalityt::equality2(const exprt &e1, const exprt &e2)
2626
{
27-
const typet &type=e1.type();
27+
PRECONDITION(e1.type() == e2.type());
2828

29-
if(e2.type()!=e1.type())
30-
throw "equality got different types";
29+
const typet &type = e1.type();
3130

3231
// check for syntactical equality
3332

@@ -36,9 +35,8 @@ literalt equalityt::equality2(const exprt &e1, const exprt &e2)
3635

3736
// check for boolean equality
3837

39-
if(type.id()==ID_bool)
40-
throw "equalityt got boolean equality";
41-
// return lequal(convert(e1), convert(e2));
38+
INVARIANT(
39+
type.id() != ID_bool, "method shall not be used to compare Boolean types");
4240

4341
// look it up
4442

src/solvers/flattening/flatten_byte_operators.cpp

Lines changed: 72 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,15 @@ static exprt unpack_rec(
5151
mp_integer element_width=pointer_offset_bits(subtype, ns);
5252
// this probably doesn't really matter
5353
#if 0
54-
if(element_width<=0)
55-
throw "cannot unpack array with non-constant element width:\n"+
56-
type.pretty();
57-
else if(element_width%8!=0)
58-
throw "cannot unpack array of non-byte aligned elements:\n"+
59-
type.pretty();
54+
INVARIANT(
55+
element_width > 0,
56+
"element width of array should be constant",
57+
irep_pretty_diagnosticst(type));
58+
59+
INVARIANT(
60+
element_width % 8 == 0,
61+
"elements in array should be byte-aligned",
62+
irep_pretty_diagnosticst(type));
6063
#endif
6164

6265
if(!unpack_byte_array && element_width==8)
@@ -199,8 +202,6 @@ exprt flatten_byte_extract(
199202
// big-endian: (short)concatenation(01,02)=0x0102
200203
// little-endian: (short)concatenation(03,04)=0x0304
201204

202-
assert(src.operands().size()==2);
203-
204205
PRECONDITION(
205206
src.id() == ID_byte_extract_little_endian ||
206207
src.id() == ID_byte_extract_big_endian);
@@ -345,14 +346,14 @@ exprt flatten_byte_update(
345346
const namespacet &ns,
346347
bool negative_offset)
347348
{
348-
assert(src.operands().size()==3);
349+
mp_integer element_size = pointer_offset_size(src.value().type(), ns);
349350

350-
mp_integer element_size=
351-
pointer_offset_size(src.op2().type(), ns);
352-
if(element_size<0)
353-
throw "byte_update of unknown width:\n"+src.pretty();
351+
INVARIANT_WITH_DIAGNOSTICS(
352+
element_size >= 0,
353+
"size of type in bytes must be known",
354+
irep_pretty_diagnosticst(src));
354355

355-
const typet &t=ns.follow(src.op0().type());
356+
const typet &t = ns.follow(src.op().type());
356357

357358
if(t.id()==ID_array)
358359
{
@@ -368,44 +369,48 @@ exprt flatten_byte_update(
368369
{
369370
mp_integer sub_size=pointer_offset_size(subtype, ns);
370371

371-
if(sub_size==-1)
372-
throw "can't flatten byte_update for sub-type without size";
372+
INVARIANT(
373+
sub_size >= 0,
374+
"bit width (rounded to full bytes) of subtype must be known");
373375

374376
// byte array?
375377
if(sub_size==1)
376378
{
377379
// apply 'array-update-with' element_size times
378-
exprt result=src.op0();
380+
exprt result = src.op();
379381

380382
for(mp_integer i=0; i<element_size; ++i)
381383
{
382-
exprt i_expr=from_integer(i, ns.follow(src.op1().type()));
384+
exprt i_expr = from_integer(i, ns.follow(src.offset().type()));
383385

384386
exprt new_value;
385387

386388
if(i==0 && element_size==1) // bytes?
387389
{
388-
new_value=src.op2();
390+
new_value = src.value();
389391
if(new_value.type()!=subtype)
390392
new_value.make_typecast(subtype);
391393
}
392394
else
393395
{
396+
INVARIANT(
397+
src.id() == ID_byte_update_little_endian ||
398+
src.id() == ID_byte_update_big_endian,
399+
"byte update expression should either be little or big endian");
400+
394401
byte_extract_exprt byte_extract_expr(
395-
src.id()==ID_byte_update_little_endian?
396-
ID_byte_extract_little_endian:
397-
src.id()==ID_byte_update_big_endian?
398-
ID_byte_extract_big_endian:
399-
throw "unexpected src.id() in flatten_byte_update",
402+
src.id() == ID_byte_update_little_endian
403+
? ID_byte_extract_little_endian
404+
: ID_byte_extract_big_endian,
400405
subtype);
401406

402-
byte_extract_expr.op()=src.op2();
407+
byte_extract_expr.op() = src.value();
403408
byte_extract_expr.offset()=i_expr;
404409

405410
new_value=flatten_byte_extract(byte_extract_expr, ns);
406411
}
407412

408-
const plus_exprt where(src.op1(), i_expr);
413+
const plus_exprt where(src.offset(), i_expr);
409414

410415
with_exprt with_expr(result, where, new_value);
411416
with_expr.type()=src.type();
@@ -417,34 +422,34 @@ exprt flatten_byte_update(
417422
}
418423
else // sub_size!=1
419424
{
420-
exprt result=src.op0();
425+
exprt result = src.op();
421426

422427
// Number of potentially affected array cells:
423428
mp_integer num_elements=
424429
element_size/sub_size+((element_size%sub_size==0)?1:2);
425430

426-
const auto &offset_type=ns.follow(src.op1().type());
431+
const auto &offset_type = ns.follow(src.offset().type());
427432
exprt zero_offset=from_integer(0, offset_type);
428433

429434
exprt sub_size_expr=from_integer(sub_size, offset_type);
430435
exprt element_size_expr=from_integer(element_size, offset_type);
431436

432437
// First potentially affected cell:
433-
div_exprt first_cell(src.op1(), sub_size_expr);
438+
div_exprt first_cell(src.offset(), sub_size_expr);
434439

435440
for(mp_integer i=0; i<num_elements; ++i)
436441
{
437442
plus_exprt cell_index(first_cell, from_integer(i, offset_type));
438443
mult_exprt cell_offset(cell_index, sub_size_expr);
439-
index_exprt old_cell_value(src.op0(), cell_index, subtype);
444+
index_exprt old_cell_value(src.op(), cell_index, subtype);
440445
bool is_first_cell=i==0;
441446
bool is_last_cell=i==num_elements-1;
442447

443448
exprt new_value;
444449
exprt stored_value_offset;
445450
if(element_size<=sub_size)
446451
{
447-
new_value=src.op2();
452+
new_value = src.value();
448453
stored_value_offset=zero_offset;
449454
}
450455
else
@@ -458,19 +463,20 @@ exprt flatten_byte_update(
458463
stored_value_offset=
459464
from_integer(element_size-sub_size, offset_type);
460465
else
461-
stored_value_offset=minus_exprt(cell_offset, src.op1());
462-
463-
auto extract_opcode=
464-
src.id()==ID_byte_update_little_endian ?
465-
ID_byte_extract_little_endian :
466-
src.id()==ID_byte_update_big_endian ?
467-
ID_byte_extract_big_endian :
468-
throw "unexpected src.id() in flatten_byte_update";
466+
stored_value_offset = minus_exprt(cell_offset, src.offset());
467+
468+
INVARIANT(
469+
src.id() == ID_byte_update_little_endian ||
470+
src.id() == ID_byte_update_big_endian,
471+
"byte update expression should either be little or big endian");
472+
469473
byte_extract_exprt byte_extract_expr(
470-
extract_opcode,
471-
element_size<sub_size ? src.op2().type() : subtype);
474+
src.id() == ID_byte_update_little_endian
475+
? ID_byte_extract_little_endian
476+
: ID_byte_extract_big_endian,
477+
element_size < sub_size ? src.value().type() : subtype);
472478

473-
byte_extract_expr.op()=src.op2();
479+
byte_extract_expr.op() = src.value();
474480
byte_extract_expr.offset()=stored_value_offset;
475481

476482
new_value=flatten_byte_extract(byte_extract_expr, ns);
@@ -482,15 +488,13 @@ exprt flatten_byte_update(
482488
// target array cell.
483489
exprt overwrite_offset;
484490
if(is_first_cell)
485-
overwrite_offset=mod_exprt(src.op1(), sub_size_expr);
491+
overwrite_offset = mod_exprt(src.offset(), sub_size_expr);
486492
else if(is_last_cell)
487493
{
488494
// This is intentionally negated; passing is_last_cell
489495
// to flatten below leads to it being negated again later.
490-
overwrite_offset=
491-
minus_exprt(
492-
minus_exprt(cell_offset, src.op1()),
493-
stored_value_offset);
496+
overwrite_offset = minus_exprt(
497+
minus_exprt(cell_offset, src.offset()), stored_value_offset);
494498
}
495499
else
496500
overwrite_offset=zero_offset;
@@ -517,9 +521,10 @@ exprt flatten_byte_update(
517521
}
518522
else
519523
{
520-
throw
521-
"flatten_byte_update can only do arrays of scalars right now, "
522-
"but got "+subtype.id_string();
524+
PRECONDITION_WITH_DIAGNOSTICS(
525+
false,
526+
"flatten_byte_update can only do arrays of scalars right now",
527+
subtype.id_string());
523528
}
524529
}
525530
else if(t.id()==ID_signedbv ||
@@ -530,11 +535,12 @@ exprt flatten_byte_update(
530535
{
531536
// do a shift, mask and OR
532537
mp_integer type_width=pointer_offset_bits(t, ns);
533-
assert(type_width>0);
538+
CHECK_RETURN(type_width > 0);
534539
std::size_t width=integer2size_t(type_width);
535540

536-
if(element_size*8>width)
537-
throw "flatten_byte_update to update element that is too large";
541+
INVARIANT(
542+
element_size * 8 <= width,
543+
"element bit width must not be larger than width indicated by type");
538544

539545
// build mask
540546
exprt mask=
@@ -544,16 +550,16 @@ exprt flatten_byte_update(
544550
exprt value_extended;
545551

546552
if(width>integer2unsigned(element_size)*8)
547-
value_extended=
548-
concatenation_exprt(
549-
from_integer(
550-
0, unsignedbv_typet(width-integer2unsigned(element_size)*8)),
551-
src.op2(), t);
553+
value_extended = concatenation_exprt(
554+
from_integer(
555+
0, unsignedbv_typet(width - integer2unsigned(element_size) * 8)),
556+
src.value(),
557+
t);
552558
else
553-
value_extended=src.op2();
559+
value_extended = src.value();
554560

555-
const typet &offset_type=ns.follow(src.op1().type());
556-
mult_exprt offset_times_eight(src.op1(), from_integer(8, offset_type));
561+
const typet &offset_type = ns.follow(src.offset().type());
562+
mult_exprt offset_times_eight(src.offset(), from_integer(8, offset_type));
557563

558564
binary_predicate_exprt offset_ge_zero(
559565
offset_times_eight,
@@ -578,7 +584,7 @@ exprt flatten_byte_update(
578584
}
579585

580586
// original_bits &= ~mask
581-
bitand_exprt bitand_expr(src.op0(), bitnot_exprt(mask_shifted));
587+
bitand_exprt bitand_expr(src.op(), bitnot_exprt(mask_shifted));
582588

583589
// original_bits |= newvalue
584590
bitor_exprt bitor_expr(bitand_expr, value_shifted);
@@ -587,8 +593,10 @@ exprt flatten_byte_update(
587593
}
588594
else
589595
{
590-
throw "flatten_byte_update can only do array and scalars "
591-
"right now, but got "+t.id_string();
596+
PRECONDITION_WITH_DIAGNOSTICS(
597+
false,
598+
"flatten_byte_update can only do arrays and scalars right now",
599+
t.id_string());
592600
}
593601
}
594602

src/solvers/flattening/functions.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ Author: Daniel Kroening, [email protected]
88

99
#include "functions.h"
1010

11-
#include <cassert>
12-
1311
#include <util/std_types.h>
1412
#include <util/std_expr.h>
1513

@@ -32,7 +30,7 @@ void functionst::add_function_constraints()
3230
exprt functionst::arguments_equal(const exprt::operandst &o1,
3331
const exprt::operandst &o2)
3432
{
35-
assert(o1.size()==o2.size());
33+
PRECONDITION(o1.size() == o2.size());
3634

3735
if(o1.empty())
3836
return true_exprt();

src/solvers/flattening/pointer_logic.cpp

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

1212
#include "pointer_logic.h"
1313

14-
#include <cassert>
15-
1614
#include <util/arith_tools.h>
1715
#include <util/c_types.h>
1816
#include <util/invariant.h>
@@ -52,13 +50,11 @@ std::size_t pointer_logict::add_object(const exprt &expr)
5250

5351
if(expr.id()==ID_index)
5452
{
55-
assert(expr.operands().size()==2);
56-
return add_object(expr.op0());
53+
return add_object(to_index_expr(expr).array());
5754
}
5855
else if(expr.id()==ID_member)
5956
{
60-
assert(expr.operands().size()==1);
61-
return add_object(expr.op0());
57+
return add_object(to_member_expr(expr).compound());
6258
}
6359

6460
return objects.number(expr);
@@ -149,12 +145,15 @@ exprt pointer_logict::object_rec(
149145

150146
for(const auto &c : components)
151147
{
152-
assert(offset>=current_offset);
148+
INVARIANT(
149+
offset >= current_offset,
150+
"when the object has not been found yet its offset must not be smaller"
151+
"than the offset of the current struct component");
153152

154153
const typet &subtype=c.type();
155154

156155
mp_integer sub_size=pointer_offset_size(subtype, ns);
157-
assert(sub_size>0);
156+
CHECK_RETURN(sub_size > 0);
158157
mp_integer new_offset=current_offset+sub_size;
159158

160159
if(new_offset>offset)
@@ -166,9 +165,7 @@ exprt pointer_logict::object_rec(
166165
offset-current_offset, pointer_type, tmp);
167166
}
168167

169-
assert(new_offset<=offset);
170168
current_offset=new_offset;
171-
assert(current_offset<=offset);
172169
}
173170

174171
return src;
@@ -183,7 +180,7 @@ pointer_logict::pointer_logict(const namespacet &_ns):ns(_ns)
183180
{
184181
// add NULL
185182
null_object=objects.number(exprt(ID_NULL));
186-
assert(null_object==0);
183+
CHECK_RETURN(null_object == 0);
187184

188185
// add INVALID
189186
invalid_object=objects.number(exprt("INVALID"));

0 commit comments

Comments
 (0)