Skip to content

Commit 7de1747

Browse files
committed
Allow loop contracts annotated to GOTO statement
1 parent f18b509 commit 7de1747

File tree

2 files changed

+33
-13
lines changed

2 files changed

+33
-13
lines changed

src/ansi-c/goto-conversion/goto_convert.cpp

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,12 +1005,12 @@ void goto_convertt::convert_assume(
10051005
void goto_convertt::convert_loop_contracts(
10061006
const codet &code,
10071007
goto_programt::targett loop,
1008-
const irep_idt &mode)
1008+
bool check_side_effect)
10091009
{
10101010
auto assigns = static_cast<const unary_exprt &>(code.find(ID_C_spec_assigns));
10111011
if(assigns.is_not_nil())
10121012
{
1013-
PRECONDITION(loop->is_goto());
1013+
PRECONDITION(loop->is_goto() || loop->is_incomplete_goto());
10141014
loop->condition_nonconst().add(ID_C_spec_assigns).swap(assigns.op());
10151015
}
10161016

@@ -1020,11 +1020,20 @@ void goto_convertt::convert_loop_contracts(
10201020
{
10211021
if(has_subexpr(invariant, ID_side_effect))
10221022
{
1023-
throw incorrect_goto_program_exceptiont(
1024-
"Loop invariant is not side-effect free.", code.find_source_location());
1023+
if(check_side_effect)
1024+
{
1025+
throw incorrect_goto_program_exceptiont(
1026+
"Loop invariant is not side-effect free.",
1027+
code.find_source_location());
1028+
}
1029+
else
1030+
{
1031+
warning().source_location = code.find_source_location();
1032+
warning() << "Loop invariants is not side-effect-free." << eom;
1033+
}
10251034
}
10261035

1027-
PRECONDITION(loop->is_goto());
1036+
PRECONDITION(loop->is_goto() || loop->is_incomplete_goto());
10281037
loop->condition_nonconst().add(ID_C_spec_loop_invariant).swap(invariant);
10291038
}
10301039

@@ -1034,12 +1043,20 @@ void goto_convertt::convert_loop_contracts(
10341043
{
10351044
if(has_subexpr(decreases_clause, ID_side_effect))
10361045
{
1037-
throw incorrect_goto_program_exceptiont(
1038-
"Decreases clause is not side-effect free.",
1039-
code.find_source_location());
1046+
if(check_side_effect)
1047+
{
1048+
throw incorrect_goto_program_exceptiont(
1049+
"Decreases clause is not side-effect free.",
1050+
code.find_source_location());
1051+
}
1052+
else
1053+
{
1054+
warning().source_location = code.find_source_location();
1055+
warning() << "Decreases clause is not side-effect-free." << eom;
1056+
}
10401057
}
10411058

1042-
PRECONDITION(loop->is_goto());
1059+
PRECONDITION(loop->is_goto() || loop->is_incomplete_goto());
10431060
loop->condition_nonconst().add(ID_C_spec_decreases).swap(decreases_clause);
10441061
}
10451062
}
@@ -1123,7 +1140,7 @@ void goto_convertt::convert_for(
11231140
goto_programt::make_goto(u, true_exprt(), code.source_location()));
11241141

11251142
// assigns clause, loop invariant and decreases clause
1126-
convert_loop_contracts(code, y, mode);
1143+
convert_loop_contracts(code, y);
11271144

11281145
dest.destructive_append(sideeffects);
11291146
dest.destructive_append(tmp_v);
@@ -1181,7 +1198,7 @@ void goto_convertt::convert_while(
11811198
convert(code.body(), tmp_x, mode);
11821199

11831200
// assigns clause, loop invariant and decreases clause
1184-
convert_loop_contracts(code, y, mode);
1201+
convert_loop_contracts(code, y);
11851202

11861203
dest.destructive_append(tmp_branch);
11871204
dest.destructive_append(tmp_x);
@@ -1250,7 +1267,7 @@ void goto_convertt::convert_dowhile(
12501267
y->complete_goto(w);
12511268

12521269
// assigns_clause, loop invariant and decreases clause
1253-
convert_loop_contracts(code, y, mode);
1270+
convert_loop_contracts(code, y);
12541271

12551272
dest.destructive_append(tmp_w);
12561273
dest.destructive_append(sideeffects);
@@ -1512,6 +1529,9 @@ void goto_convertt::convert_goto(const code_gotot &code, goto_programt &dest)
15121529
goto_programt::targett t =
15131530
dest.add(goto_programt::make_incomplete_goto(code, code.source_location()));
15141531

1532+
// Loop contracts annotated in GOTO
1533+
convert_loop_contracts(code, t, false);
1534+
15151535
// remember it to do the target later
15161536
targets.gotos.emplace_back(t, targets.scope_stack.get_current_node());
15171537
}

src/ansi-c/goto-conversion/goto_convert_class.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ class goto_convertt : public messaget
244244
void convert_loop_contracts(
245245
const codet &code,
246246
goto_programt::targett loop,
247-
const irep_idt &mode);
247+
bool check_side_effect = true);
248248
void
249249
convert_for(const code_fort &code, goto_programt &dest, const irep_idt &mode);
250250
void convert_while(

0 commit comments

Comments
 (0)