Skip to content

Commit 1a2a1dd

Browse files
committed
[WIP] Filter generated assertions
This changes C/C++ goto checks to be generated at compile time, and filtered-out based on command-line options at analysis time.
1 parent 91e929f commit 1a2a1dd

File tree

3 files changed

+145
-0
lines changed

3 files changed

+145
-0
lines changed

src/ansi-c/goto_check_c.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class goto_check_ct
7272
enable_simplify = _options.get_bool_option("simplify");
7373
enable_nan_check = _options.get_bool_option("nan-check");
7474
retain_trivial = _options.get_bool_option("retain-trivial-checks");
75+
// TODO: the following aren't C specific
7576
enable_assert_to_assume = _options.get_bool_option("assert-to-assume");
7677
enable_assertions = _options.get_bool_option("assertions");
7778
enable_built_in_assertions =
@@ -1511,6 +1512,7 @@ void goto_check_ct::bounds_check(const exprt &expr, const guardt &guard)
15111512
if(!enable_bounds_check)
15121513
return;
15131514

1515+
// TODO: get rid of this
15141516
if(
15151517
expr.find(ID_C_bounds_check).is_not_nil() &&
15161518
!expr.get_bool(ID_C_bounds_check))
@@ -2181,6 +2183,7 @@ void goto_check_ct::goto_check(
21812183
const notequal_exprt not_eq_null(
21822184
pointer, null_pointer_exprt(to_pointer_type(pointer.type())));
21832185

2186+
// TODO this is unconditional
21842187
add_guarded_property(
21852188
not_eq_null,
21862189
"throwing null",

src/goto-programs/goto_check.cpp

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

1616
#include <ansi-c/goto_check_c.h>
1717

18+
#include "remove_skip.h"
19+
1820
void goto_check(
1921
const irep_idt &function_identifier,
2022
goto_functionst::goto_functiont &goto_function,
@@ -47,3 +49,140 @@ void goto_check(
4749
{
4850
goto_check_c(options, goto_model, message_handler);
4951
}
52+
53+
void remove_disabled_checks(
54+
const optionst &options,
55+
goto_modelt &goto_model,
56+
message_handlert &message_handler)
57+
{
58+
// done
59+
const bool enable_bounds_check = options.get_bool_option("bounds-check");
60+
const bool enable_pointer_check = options.get_bool_option("pointer-check");
61+
// done
62+
const bool enable_memory_leak_check = options.get_bool_option("memory-leak-check");
63+
// done
64+
const bool enable_div_by_zero_check = options.get_bool_option("div-by-zero-check");
65+
// done
66+
const bool enable_enum_range_check = options.get_bool_option("enum-range-check");
67+
const bool enable_signed_overflow_check = options.get_bool_option("signed-overflow-check");
68+
const bool enable_unsigned_overflow_check = options.get_bool_option("unsigned-overflow-check");
69+
const bool enable_pointer_overflow_check = options.get_bool_option("pointer-overflow-check");
70+
const bool enable_conversion_check = options.get_bool_option("conversion-check");
71+
// done
72+
const bool enable_undefined_shift_check = options.get_bool_option("undefined-shift-check");
73+
const bool enable_float_overflow_check = options.get_bool_option("float-overflow-check");
74+
// done
75+
const bool enable_nan_check = options.get_bool_option("nan-check");
76+
const bool enable_assert_to_assume = options.get_bool_option("assert-to-assume");
77+
const bool enable_assertions = options.get_bool_option("assertions");
78+
const bool enable_built_in_assertions = options.get_bool_option("built-in-assertions");
79+
const bool enable_assumptions = options.get_bool_option("assumptions");
80+
// done
81+
const bool error_labels = options.get_list_option("error-label");
82+
// done
83+
const bool enable_pointer_primitive_check = options.get_bool_option("pointer-primitive-check");
84+
85+
const bool enable_simplify = options.get_bool_option("simplify");
86+
const bool retain_trivial = options.get_bool_option("retain-trivial-checks");
87+
88+
for(auto &entry : goto_model.goto_functions.function_map)
89+
{
90+
bool changed = false;
91+
92+
for(auto &instruction : entry.second.body.instructions)
93+
{
94+
if(instruction.is_assign())
95+
{
96+
if(!enable_pointer_check && !enable_pointer_primitive_check &&
97+
instruction.get_assign_lhs().id() == ID_symbol &&
98+
to_symbol_expr(instruction.get_assign_lhs()).get_identifier() == CPROVER_PREFIX "dead_object")
99+
{
100+
instruction->make_skip(), changed = true;
101+
}
102+
}
103+
else if(!instruction.is_assert())
104+
continue;
105+
106+
const irep_idt &property_class = instruction.get_property_class();
107+
108+
if(!error_labels && property_class == "error label")
109+
instruction->make_skip(), changed = true;
110+
else if(!enable_div_by_zero_check && property_class == "division-by-zero")
111+
{
112+
instruction->make_skip(), changed = true;
113+
}
114+
else if(!enable_enum_range_check && property_class == "enum-range-check")
115+
instruction->make_skip(), changed = true;
116+
else if(!enable_undefined_shift_check && property_class == "undefined-shift")
117+
instruction->make_skip(), changed = true;
118+
else if(!enable_signed_overflow_check && property_class == "overflow")
119+
{
120+
// "result of signed mod is not representable"
121+
"arithmetic overflow on signed division",
122+
"arithmetic overflow on signed unary minus",
123+
"arithmetic overflow on signed shl",
124+
"arithmetic overflow on signed " + expr.id_string(),
125+
instruction->make_skip(), changed = true;
126+
}
127+
else if(!enable_unsigned_overflow_check && property_class == "overflow")
128+
{
129+
"arithmetic overflow on unsigned unary minus",
130+
"arithmetic overflow on unsigned " + expr.id_string(),
131+
}
132+
else if(!enable_float_overflow_check && property_class == "overflow")
133+
{
134+
"arithmetic overflow on floating-point typecast",
135+
"arithmetic overflow on floating-point division",
136+
"arithmetic overflow on floating-point " + kind,
137+
}
138+
else if(!enable_conversion_check && property_class == "overflow")
139+
{
140+
// "arithmetic overflow on signed type conversion"
141+
"arithmetic overflow on unsigned to signed type conversion",
142+
"arithmetic overflow on float to signed integer type conversion",
143+
"arithmetic overflow on signed to unsigned type conversion",
144+
"arithmetic overflow on unsigned to unsigned type conversion",
145+
"arithmetic overflow on float to unsigned integer type conversion",
146+
}
147+
else if(!enable_nan_check && property_class == "NaN")
148+
{
149+
instruction->make_skip(), changed = true;
150+
}
151+
else if(!enable_pointer_check && property_class == "pointer")
152+
{
153+
}
154+
else if(!enable_pointer_check && property_class == "pointer arithmetic")
155+
{
156+
}
157+
else if(!enable_pointer_check && property_class == "pointer dereference")
158+
{
159+
}
160+
else if(!enable_pointer_overflow_check && property_class == "overflow")
161+
{
162+
// same as signed/unsigned overflow
163+
}
164+
else if(!enable_pointer_overflow_check && property_class == "pointer arithmetic")
165+
{
166+
}
167+
else if(!enable_pointer_primitive_check && property_class == "pointer primitives")
168+
{
169+
instruction->make_skip(), changed = true;
170+
}
171+
else if(!enable_bounds_check && property_class == "array bounds")
172+
{
173+
instruction->make_skip(), changed = true;
174+
}
175+
else if(!enable_bounds_check && property_class == "bit count")
176+
{
177+
instruction->make_skip(), changed = true;
178+
}
179+
else if(!enable_memory_leak_check && property_class == "memory-leak")
180+
{
181+
instruction->make_skip(), changed = true;
182+
}
183+
}
184+
185+
if(changed)
186+
remove_skip(entry.second.body);
187+
}
188+
}

src/goto-programs/goto_check.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,7 @@ void goto_check(
3434

3535
void goto_check(const optionst &, goto_modelt &, message_handlert &);
3636

37+
void remove_disabled_checks(
38+
const optionst &, goto_modelt &, message_handlert &);
39+
3740
#endif // CPROVER_GOTO_PROGRAMS_GOTO_CHECK_H

0 commit comments

Comments
 (0)