@@ -43,7 +43,7 @@ void goto_inlinet::parameter_assignments(
43
43
44
44
const code_typet::parameterst ¶meter_types=
45
45
code_type.parameters ();
46
-
46
+
47
47
// iterates over the types of the parameters
48
48
for (code_typet::parameterst::const_iterator
49
49
it2=parameter_types.begin ();
@@ -72,7 +72,7 @@ void goto_inlinet::parameter_assignments(
72
72
decl->code =code_declt (symbol.symbol_expr ());
73
73
decl->code .add_source_location ()=source_location;
74
74
decl->source_location =source_location;
75
- decl->function =function_name;
75
+ decl->function =function_name;
76
76
}
77
77
78
78
// this is the actual parameter
@@ -93,7 +93,7 @@ void goto_inlinet::parameter_assignments(
93
93
94
94
// nil means "don't assign"
95
95
if (actual.is_nil ())
96
- {
96
+ {
97
97
}
98
98
else
99
99
{
@@ -103,7 +103,7 @@ void goto_inlinet::parameter_assignments(
103
103
{
104
104
const typet &f_partype = ns.follow (par_type);
105
105
const typet &f_acttype = ns.follow (actual.type ());
106
-
106
+
107
107
// we are willing to do some conversion
108
108
if ((f_partype.id ()==ID_pointer &&
109
109
f_acttype.id ()==ID_pointer) ||
@@ -118,7 +118,7 @@ void goto_inlinet::parameter_assignments(
118
118
f_partype.id ()==ID_bool) &&
119
119
(f_acttype.id ()==ID_signedbv ||
120
120
f_acttype.id ()==ID_unsignedbv ||
121
- f_acttype.id ()==ID_bool))
121
+ f_acttype.id ()==ID_bool))
122
122
{
123
123
actual.make_typecast (par_type);
124
124
}
@@ -144,7 +144,7 @@ void goto_inlinet::parameter_assignments(
144
144
dest.add_instruction (ASSIGN);
145
145
dest.instructions .back ().source_location =source_location;
146
146
dest.instructions .back ().code .swap (assignment);
147
- dest.instructions .back ().function =function_name;
147
+ dest.instructions .back ().function =function_name;
148
148
}
149
149
150
150
if (it1!=arguments.end ())
@@ -177,7 +177,7 @@ void goto_inlinet::parameter_destruction(
177
177
{
178
178
const code_typet::parameterst ¶meter_types=
179
179
code_type.parameters ();
180
-
180
+
181
181
// iterates over the types of the parameters
182
182
for (code_typet::parameterst::const_iterator
183
183
it=parameter_types.begin ();
@@ -203,7 +203,7 @@ void goto_inlinet::parameter_destruction(
203
203
dead->code =code_deadt (symbol.symbol_expr ());
204
204
dead->code .add_source_location ()=source_location;
205
205
dead->source_location =source_location;
206
- dead->function =function_name;
206
+ dead->function =function_name;
207
207
}
208
208
}
209
209
}
@@ -242,10 +242,10 @@ void goto_inlinet::replace_return(
242
242
warning_msg();
243
243
continue;
244
244
}
245
-
245
+
246
246
goto_programt tmp;
247
247
goto_programt::targett assignment=tmp.add_instruction(ASSIGN);
248
-
248
+
249
249
code_assignt code_assign(lhs, it->code.op0());
250
250
251
251
// this may happen if the declared return type at the call site
@@ -257,28 +257,28 @@ void goto_inlinet::replace_return(
257
257
assignment->code=code_assign;
258
258
assignment->source_location=it->source_location;
259
259
assignment->function=it->function;
260
-
260
+
261
261
if(constrain.is_not_nil() && !constrain.is_true())
262
262
{
263
263
codet constrain(ID_bp_constrain);
264
264
constrain.reserve_operands(2);
265
265
constrain.move_to_operands(assignment->code);
266
266
constrain.copy_to_operands(constrain);
267
267
}
268
-
268
+
269
269
dest.insert_before_swap(it, *assignment);
270
270
it++;
271
271
}
272
272
else if(!it->code.operands().empty())
273
273
{
274
274
goto_programt tmp;
275
275
goto_programt::targett expression=tmp.add_instruction(OTHER);
276
-
276
+
277
277
expression->code=codet(ID_expression);
278
278
expression->code.move_to_operands(it->code.op0());
279
279
expression->source_location=it->source_location;
280
280
expression->function=it->function;
281
-
281
+
282
282
dest.insert_before_swap(it, *expression);
283
283
it++;
284
284
}
@@ -294,7 +294,7 @@ void goto_inlinet::replace_return(
294
294
<< it->code .pretty () << eom;
295
295
continue ;
296
296
}
297
-
297
+
298
298
code_assignt code_assign (lhs, it->code .op0 ());
299
299
300
300
// this may happen if the declared return type at the call site
@@ -357,7 +357,7 @@ void replace_location(
357
357
irep_idt property_id=dest.get_property_id ();
358
358
359
359
dest=new_location;
360
-
360
+
361
361
if (comment!=irep_idt ()) dest.set_comment (comment);
362
362
if (property_class!=irep_idt ()) dest.set_property_class (property_class);
363
363
if (property_id!=irep_idt ()) dest.set_property_id (property_id);
@@ -409,7 +409,7 @@ void goto_inlinet::expand_function_call(
409
409
{
410
410
// look it up
411
411
const irep_idt identifier=function.get_identifier ();
412
-
412
+
413
413
// we ignore certain calls
414
414
if (identifier==" __CPROVER_cleanup" ||
415
415
identifier==" __CPROVER_set_must" ||
@@ -421,7 +421,7 @@ void goto_inlinet::expand_function_call(
421
421
target++;
422
422
return ; // ignore
423
423
}
424
-
424
+
425
425
// see if we are already expanding it
426
426
if (recursion_set.find (identifier)!=recursion_set.end ())
427
427
{
@@ -435,8 +435,9 @@ void goto_inlinet::expand_function_call(
435
435
// Uh. Buh. Give up.
436
436
warning ().source_location =function.find_source_location ();
437
437
warning () << " recursion is ignored" << eom;
438
+ is_recursion_detected=true ;
438
439
target->make_skip ();
439
-
440
+
440
441
target++;
441
442
return ;
442
443
}
@@ -456,10 +457,10 @@ void goto_inlinet::expand_function_call(
456
457
error () << " failed to find function `" << identifier << " '" << eom;
457
458
throw 0 ;
458
459
}
459
-
460
+
460
461
const goto_functionst::goto_functiont &f=m_it->second ;
461
462
462
- // see if we need to inline this
463
+ // see if we need to inline this
463
464
if (!full)
464
465
{
465
466
if (!f.body_available () ||
@@ -479,10 +480,10 @@ void goto_inlinet::expand_function_call(
479
480
480
481
goto_programt tmp2;
481
482
tmp2.copy_from (f.body );
482
-
483
+
483
484
assert (tmp2.instructions .back ().is_end_function ());
484
485
tmp2.instructions .back ().type =LOCATION;
485
-
486
+
486
487
replace_return (tmp2, lhs, constrain);
487
488
488
489
goto_programt tmp;
@@ -494,11 +495,11 @@ void goto_inlinet::expand_function_call(
494
495
{
495
496
source_locationt new_source_location=
496
497
function.find_source_location ();
497
-
498
+
498
499
if (new_source_location.is_not_nil ())
499
500
{
500
501
new_source_location.set_hide ();
501
-
502
+
502
503
Forall_goto_program_instructions (it, tmp)
503
504
{
504
505
if (it->function ==identifier)
@@ -520,10 +521,10 @@ void goto_inlinet::expand_function_call(
520
521
}
521
522
}
522
523
523
- // set up location instruction for function call
524
+ // set up location instruction for function call
524
525
target->type =LOCATION;
525
526
target->code .clear ();
526
-
527
+
527
528
goto_programt::targett next_target (target);
528
529
next_target++;
529
530
@@ -551,7 +552,7 @@ void goto_inlinet::expand_function_call(
551
552
t->source_location =target->source_location ;
552
553
t->function =target->function ;
553
554
}
554
-
555
+
555
556
// return value
556
557
if (lhs.is_not_nil ())
557
558
{
@@ -560,7 +561,7 @@ void goto_inlinet::expand_function_call(
560
561
561
562
code_assignt code (lhs, rhs);
562
563
code.add_source_location ()=target->source_location ;
563
-
564
+
564
565
goto_programt::targett t=tmp.add_instruction (ASSIGN);
565
566
t->source_location =target->source_location ;
566
567
t->function =target->function ;
@@ -592,7 +593,7 @@ Function: goto_inlinet::goto_inline
592
593
void goto_inlinet::goto_inline (goto_programt &dest)
593
594
{
594
595
goto_inline_rec (dest, true );
595
- replace_return (dest,
596
+ replace_return (dest,
596
597
static_cast <const exprt &>(get_nil_irep ()),
597
598
static_cast <const exprt &>(get_nil_irep ()));
598
599
}
@@ -614,18 +615,18 @@ void goto_inlinet::goto_inline_rec(
614
615
bool full)
615
616
{
616
617
// already done?
617
-
618
+
618
619
if (finished_inlining_set.find (f_it->first )!=
619
620
finished_inlining_set.end ())
620
621
return ; // yes
621
-
622
+
622
623
// do it
623
-
624
+
624
625
goto_inline_rec (f_it->second .body , full);
625
-
626
+
626
627
// remember we did it
627
-
628
- finished_inlining_set.insert (f_it->first );
628
+
629
+ finished_inlining_set.insert (f_it->first );
629
630
}
630
631
631
632
/* ******************************************************************\
@@ -655,7 +656,7 @@ void goto_inlinet::goto_inline_rec(goto_programt &dest, bool full)
655
656
656
657
if (changed)
657
658
{
658
- remove_skip (dest);
659
+ remove_skip (dest);
659
660
dest.update ();
660
661
}
661
662
}
@@ -711,15 +712,15 @@ bool goto_inlinet::inline_instruction(
711
712
}
712
713
}
713
714
714
- // advance iterator
715
+ // advance iterator
715
716
it++;
716
717
717
- return false ;
718
+ return false ;
718
719
}
719
720
720
721
/* ******************************************************************\
721
722
722
- Function: goto_inline
723
+ Function: goto_inlinet::operator()
723
724
724
725
Inputs:
725
726
@@ -729,43 +730,38 @@ Function: goto_inline
729
730
730
731
\*******************************************************************/
731
732
732
- void goto_inline (
733
- goto_functionst &goto_functions,
734
- const namespacet &ns,
735
- message_handlert &message_handler)
733
+ void goto_inlinet::operator ()()
736
734
{
737
- goto_inlinet goto_inline (goto_functions, ns, message_handler);
738
-
739
735
try
740
736
{
741
737
// find entry point
742
738
goto_functionst::function_mapt::iterator it=
743
739
goto_functions.function_map .find (goto_functionst::entry_point ());
744
-
740
+
745
741
if (it==goto_functions.function_map .end ())
746
742
return ;
747
-
748
- goto_inline. goto_inline (it->second .body );
743
+
744
+ goto_inline (it->second .body );
749
745
}
750
746
751
747
catch (int )
752
748
{
753
- goto_inline. error ();
749
+ error ();
754
750
throw 0 ;
755
751
}
756
752
757
753
catch (const char *e)
758
754
{
759
- goto_inline. error () << e << messaget::eom;
755
+ error () << e << messaget::eom;
760
756
throw 0 ;
761
757
}
762
758
763
759
catch (const std::string &e)
764
760
{
765
- goto_inline. error () << e << messaget::eom;
761
+ error () << e << messaget::eom;
766
762
throw 0 ;
767
763
}
768
-
764
+
769
765
// clean up
770
766
for (goto_functionst::function_mapt::iterator
771
767
it=goto_functions.function_map .begin ();
@@ -787,6 +783,27 @@ Function: goto_inline
787
783
788
784
\*******************************************************************/
789
785
786
+ void goto_inline (
787
+ goto_functionst &goto_functions,
788
+ const namespacet &ns,
789
+ message_handlert &message_handler)
790
+ {
791
+ goto_inlinet goto_inline (goto_functions, ns, message_handler);
792
+ goto_inline ();
793
+ }
794
+
795
+ /* ******************************************************************\
796
+
797
+ Function: goto_inline
798
+
799
+ Inputs:
800
+
801
+ Outputs:
802
+
803
+ Purpose:
804
+
805
+ \*******************************************************************/
806
+
790
807
void goto_inline (
791
808
goto_modelt &goto_model,
792
809
message_handlert &message_handler)
@@ -817,9 +834,9 @@ void goto_partial_inline(
817
834
goto_functions,
818
835
ns,
819
836
message_handler);
820
-
837
+
821
838
goto_inline.smallfunc_limit =_smallfunc_limit;
822
-
839
+
823
840
try
824
841
{
825
842
for (goto_functionst::function_mapt::iterator
0 commit comments