Skip to content

Commit 8a164ad

Browse files
committed
Decouple type conversion checks from arithmetic overflow
Type conversion has implementation-defined semantics, whereas integer overflow is undefined behavior in C. Thus one my want to check only the latter, in particular in SV-COMP. Fixes #307
1 parent 4906236 commit 8a164ad

File tree

2 files changed

+47
-15
lines changed

2 files changed

+47
-15
lines changed

src/analyses/goto_check.cpp

+44-14
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class goto_checkt
4141
enable_signed_overflow_check=_options.get_bool_option("signed-overflow-check");
4242
enable_unsigned_overflow_check=_options.get_bool_option("unsigned-overflow-check");
4343
enable_pointer_overflow_check=_options.get_bool_option("pointer-overflow-check");
44+
enable_conversion_check=_options.get_bool_option("conversion-check");
4445
enable_undefined_shift_check=_options.get_bool_option("undefined-shift-check");
4546
enable_float_overflow_check=_options.get_bool_option("float-overflow-check");
4647
enable_simplify=_options.get_bool_option("simplify");
@@ -74,6 +75,7 @@ class goto_checkt
7475
void pointer_overflow_check(const exprt &expr, const guardt &guard);
7576
void pointer_validity_check(const dereference_exprt &expr, const guardt &guard);
7677
void integer_overflow_check(const exprt &expr, const guardt &guard);
78+
void conversion_check(const exprt &expr, const guardt &guard);
7779
void float_overflow_check(const exprt &expr, const guardt &guard);
7880
void nan_check(const exprt &expr, const guardt &guard);
7981

@@ -105,6 +107,7 @@ class goto_checkt
105107
bool enable_signed_overflow_check;
106108
bool enable_unsigned_overflow_check;
107109
bool enable_pointer_overflow_check;
110+
bool enable_conversion_check;
108111
bool enable_undefined_shift_check;
109112
bool enable_float_overflow_check;
110113
bool enable_simplify;
@@ -305,7 +308,7 @@ void goto_checkt::mod_by_zero_check(
305308

306309
/*******************************************************************\
307310
308-
Function: goto_checkt::integer_overflow_check
311+
Function: goto_checkt::conversion_check
309312
310313
Inputs:
311314
@@ -315,25 +318,20 @@ Function: goto_checkt::integer_overflow_check
315318
316319
\*******************************************************************/
317320

318-
void goto_checkt::integer_overflow_check(
321+
void goto_checkt::conversion_check(
319322
const exprt &expr,
320323
const guardt &guard)
321324
{
322-
if(!enable_signed_overflow_check &&
323-
!enable_unsigned_overflow_check)
325+
if(!enable_conversion_check)
324326
return;
325327

326328
// First, check type.
327329
const typet &type=ns.follow(expr.type());
328330

329-
if(type.id()==ID_signedbv && !enable_signed_overflow_check)
330-
return;
331-
332-
if(type.id()==ID_unsignedbv && !enable_unsigned_overflow_check)
331+
if(type.id()!=ID_signedbv &&
332+
type.id()!=ID_unsignedbv)
333333
return;
334334

335-
// add overflow subgoal
336-
337335
if(expr.id()==ID_typecast)
338336
{
339337
// conversion to signed int may overflow
@@ -493,10 +491,41 @@ void goto_checkt::integer_overflow_check(
493491
guard);
494492
}
495493
}
494+
}
495+
}
496496

497+
/*******************************************************************\
498+
499+
Function: goto_checkt::integer_overflow_check
500+
501+
Inputs:
502+
503+
Outputs:
504+
505+
Purpose:
506+
507+
\*******************************************************************/
508+
509+
void goto_checkt::integer_overflow_check(
510+
const exprt &expr,
511+
const guardt &guard)
512+
{
513+
if(!enable_signed_overflow_check &&
514+
!enable_unsigned_overflow_check)
497515
return;
498-
}
499-
else if(expr.id()==ID_div)
516+
517+
// First, check type.
518+
const typet &type=ns.follow(expr.type());
519+
520+
if(type.id()==ID_signedbv && !enable_signed_overflow_check)
521+
return;
522+
523+
if(type.id()==ID_unsignedbv && !enable_unsigned_overflow_check)
524+
return;
525+
526+
// add overflow subgoal
527+
528+
if(expr.id()==ID_div)
500529
{
501530
assert(expr.operands().size()==2);
502531

@@ -1432,8 +1461,7 @@ void goto_checkt::check_rec(
14321461
}
14331462
else if(expr.id()==ID_plus || expr.id()==ID_minus ||
14341463
expr.id()==ID_mult ||
1435-
expr.id()==ID_unary_minus ||
1436-
expr.id()==ID_typecast)
1464+
expr.id()==ID_unary_minus)
14371465
{
14381466
if(expr.type().id()==ID_signedbv ||
14391467
expr.type().id()==ID_unsignedbv)
@@ -1454,6 +1482,8 @@ void goto_checkt::check_rec(
14541482
pointer_overflow_check(expr, guard);
14551483
}
14561484
}
1485+
else if(expr.id()==ID_typecast)
1486+
conversion_check(expr, guard);
14571487
else if(expr.id()==ID_le || expr.id()==ID_lt ||
14581488
expr.id()==ID_ge || expr.id()==ID_gt)
14591489
pointer_rel_check(expr, guard);

src/analyses/goto_check.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ void goto_check(
3232
#define GOTO_CHECK_OPTIONS \
3333
"(bounds-check)(pointer-check)(memory-leak-check)" \
3434
"(div-by-zero-check)(signed-overflow-check)(unsigned-overflow-check)" \
35-
"(pointer-overflow-check)(undefined-shift-check)" \
35+
"(pointer-overflow-check)(conversion-check)(undefined-shift-check)" \
3636
"(float-overflow-check)(nan-check)"
3737

3838
#define GOTO_CHECK_HELP \
@@ -43,6 +43,7 @@ void goto_check(
4343
" --signed-overflow-check enable signed arithmetic over- and underflow checks\n" \
4444
" --unsigned-overflow-check enable arithmetic over- and underflow checks\n" \
4545
" --pointer-overflow-check enable pointer arithmetic over- and underflow checks\n" \
46+
" --conversion-check check whether values can be represented after type cast\n" \
4647
" --undefined-shift-check check shift greater than bit-width\n" \
4748
" --float-overflow-check check floating-point for +/-Inf\n" \
4849
" --nan-check check floating-point for NaN\n" \
@@ -55,6 +56,7 @@ void goto_check(
5556
options.set_option("signed-overflow-check", cmdline.isset("signed-overflow-check")); \
5657
options.set_option("unsigned-overflow-check", cmdline.isset("unsigned-overflow-check")); \
5758
options.set_option("pointer-overflow-check", cmdline.isset("pointer-overflow-check")); \
59+
options.set_option("conversion-check", cmdline.isset("conversion-check")); \
5860
options.set_option("undefined-shift-check", cmdline.isset("undefined-shift-check")); \
5961
options.set_option("float-overflow-check", cmdline.isset("float-overflow-check")); \
6062
options.set_option("nan-check", cmdline.isset("nan-check"))

0 commit comments

Comments
 (0)