Skip to content

Commit 76491eb

Browse files
committed
Abort after failing C assert
The C standard specifies behaviour of the "assert" macro as resulting in an abort when the condition does not evaluate to true. Implement this behaviour by inserting assume(0) after assert(0). Fixes: #5505
1 parent 08c5cde commit 76491eb

File tree

5 files changed

+36
-3
lines changed

5 files changed

+36
-3
lines changed

regression/cbmc/Bool5/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CORE
22
main.c
33

4-
Generated 4 VCC\(s\), 0 remaining after simplification
4+
Generated [34] VCC\(s\), 0 remaining after simplification
55
^VERIFICATION SUCCESSFUL$
66
^EXIT=0$
77
^SIGNAL=0$

regression/cbmc/r_w_ok1/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ CORE
22
main.c
33

44
__CPROVER_[rw]_ok\(arbitrary_size, n \+ 1\): FAILURE$
5-
^\*\* 2 of 12 failed
5+
^\*\* [12] of 12 failed
66
^VERIFICATION FAILED$
77
^EXIT=10$
88
^SIGNAL=0$

regression/goto-instrument/assert1/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ main.c
55
^SIGNAL=0$
66
--
77
^warning: ignoring
8-
^[[:space:]]*IF
8+
^[[:space:]]*if

src/goto-instrument/goto_program2code.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,11 +192,23 @@ goto_programt::const_targett goto_program2codet::convert_instruction(
192192
return convert_decl(target, upper_bound, dest);
193193

194194
case ASSERT:
195+
{
195196
system_headers.insert("assert.h");
196197
dest.add(code_assertt(target->get_condition()));
197198
dest.statements().back().add_source_location().set_comment(
198199
target->source_location().get_comment());
200+
201+
goto_programt::const_targett next = target;
202+
++next;
203+
CHECK_RETURN(next != goto_program.instructions.end());
204+
if(
205+
next != upper_bound && next->is_assume() &&
206+
target->get_condition() == next->get_condition())
207+
{
208+
++target;
209+
}
199210
return target;
211+
}
200212

201213
case ASSUME:
202214
dest.add(code_assumet(target->guard));

src/goto-programs/builtin_functions.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,12 @@ void goto_convertt::do_function_call_symbol(
849849
error() << identifier << " expected not to have LHS" << eom;
850850
throw 0;
851851
}
852+
853+
// The C standard mandates that a failing assertion causes execution to
854+
// abort:
855+
dest.add(goto_programt::make_assumption(
856+
typecast_exprt::conditional_cast(arguments.front(), bool_typet()),
857+
function.source_location()));
852858
}
853859
else if(identifier == CPROVER_PREFIX "enum_is_in_range")
854860
{
@@ -1092,6 +1098,11 @@ void goto_convertt::do_function_call_symbol(
10921098
t->source_location_nonconst().set_property_class(ID_assertion);
10931099
t->source_location_nonconst().set_comment(description);
10941100
// we ignore any LHS
1101+
1102+
// The C standard mandates that a failing assertion causes execution to
1103+
// abort:
1104+
dest.add(goto_programt::make_assumption(
1105+
false_exprt(), function.source_location()));
10951106
}
10961107
else if(identifier=="__assert_rtn" ||
10971108
identifier=="__assert")
@@ -1130,6 +1141,11 @@ void goto_convertt::do_function_call_symbol(
11301141
t->source_location_nonconst().set_property_class(ID_assertion);
11311142
t->source_location_nonconst().set_comment(description);
11321143
// we ignore any LHS
1144+
1145+
// The C standard mandates that a failing assertion causes execution to
1146+
// abort:
1147+
dest.add(goto_programt::make_assumption(
1148+
false_exprt(), function.source_location()));
11331149
}
11341150
else if(identifier=="__assert_func")
11351151
{
@@ -1164,6 +1180,11 @@ void goto_convertt::do_function_call_symbol(
11641180
t->source_location_nonconst().set_property_class(ID_assertion);
11651181
t->source_location_nonconst().set_comment(description);
11661182
// we ignore any LHS
1183+
1184+
// The C standard mandates that a failing assertion causes execution to
1185+
// abort:
1186+
dest.add(goto_programt::make_assumption(
1187+
false_exprt(), function.source_location()));
11671188
}
11681189
else if(identifier==CPROVER_PREFIX "fence")
11691190
{

0 commit comments

Comments
 (0)