@@ -92,7 +92,9 @@ void remove_returnst::replace_returns(
92
92
{
93
93
if (i_it->is_return ())
94
94
{
95
- assert (i_it->code .operands ().size ()==1 );
95
+ INVARIANT (
96
+ i_it->code .operands ().size ()==1 ,
97
+ " return instructions should have one operand" );
96
98
97
99
// replace "return x;" by "fkt#return_value=x;"
98
100
symbol_exprt lhs_expr;
@@ -127,7 +129,10 @@ void remove_returnst::do_function_calls(
127
129
{
128
130
// replace "lhs=f(...)" by
129
131
// "f(...); lhs=f#return_value; DEAD f#return_value;"
130
- assert (function_call.function ().id ()==ID_symbol);
132
+ INVARIANT (
133
+ function_call.function ().id ()==ID_symbol,
134
+ " indirect function calls should have been removed prior to running "
135
+ " remove-returns" );
131
136
132
137
const irep_idt function_id=
133
138
to_symbol_expr (function_call.function ()).get_identifier ();
@@ -226,12 +231,9 @@ code_typet original_return_type(
226
231
if (rv_it!=symbol_table.symbols .end ())
227
232
{
228
233
// look up the function symbol
229
- symbol_tablet::symbolst::const_iterator s_it=
230
- symbol_table.symbols .find (function_id);
234
+ const symbolt &function_symbol=symbol_table.lookup_ref (function_id);
231
235
232
- assert (s_it!=symbol_table.symbols .end ());
233
-
234
- type=to_code_type (s_it->second .type );
236
+ type=to_code_type (function_symbol.type );
235
237
type.return_type ()=rv_it->second .type ;
236
238
}
237
239
@@ -284,18 +286,25 @@ bool remove_returnst::restore_returns(
284
286
285
287
while (!i_it->is_goto () && !i_it->is_end_function ())
286
288
{
287
- assert (i_it->is_dead ());
289
+ INVARIANT (
290
+ i_it->is_dead (),
291
+ " only dead statements should appear between "
292
+ " a return and the next goto or function end" );
288
293
i_it++;
289
294
}
290
295
291
296
if (i_it->is_goto ())
292
297
{
293
- goto_programt::const_targett target=i_it->get_target ();
294
- assert (target->is_end_function ());
298
+ INVARIANT (
299
+ i_it->get_target ()->is_end_function (),
300
+ " GOTO following return should target end of function" );
295
301
}
296
302
else
297
303
{
298
- assert (i_it->is_end_function ());
304
+ INVARIANT (
305
+ i_it->is_end_function (),
306
+ " control-flow after assigning return value should lead directly "
307
+ " to end of function" );
299
308
i_it=goto_program.instructions .insert (i_it, *i_it);
300
309
}
301
310
@@ -307,7 +316,7 @@ bool remove_returnst::restore_returns(
307
316
return false ;
308
317
}
309
318
310
- // / turns f(...); lhs=f#return_value; into x =f(...)
319
+ // / turns f(...); lhs=f#return_value; into lhs =f(...)
311
320
void remove_returnst::undo_function_calls (
312
321
goto_functionst &goto_functions,
313
322
goto_programt &goto_program)
@@ -337,7 +346,9 @@ void remove_returnst::undo_function_calls(
337
346
// and revert to "lhs=f(...);"
338
347
goto_programt::instructionst::iterator next=i_it;
339
348
++next;
340
- assert (next!=goto_program.instructions .end ());
349
+ INVARIANT (
350
+ next!=goto_program.instructions .end (),
351
+ " non-void function call must be followed by #return_value read" );
341
352
342
353
if (!next->is_assign ())
343
354
continue ;
@@ -358,8 +369,9 @@ void remove_returnst::undo_function_calls(
358
369
// remove the assignment and subsequent dead
359
370
// i_it remains valid
360
371
next=goto_program.instructions .erase (next);
361
- assert (next!=goto_program.instructions .end ());
362
- assert (next->is_dead ());
372
+ INVARIANT (
373
+ next!=goto_program.instructions .end () && next->is_dead (),
374
+ " read from #return_value should be followed by DEAD #return_value" );
363
375
// i_it remains valid
364
376
goto_program.instructions .erase (next);
365
377
}
0 commit comments