16
16
17
17
#include " class_identifier.h"
18
18
#include " goto_model.h"
19
+ #include " remove_skip.h"
19
20
#include " resolve_inherited_component.h"
20
21
21
22
class remove_virtual_functionst
@@ -29,7 +30,7 @@ class remove_virtual_functionst
29
30
30
31
bool remove_virtual_functions (goto_programt &goto_program);
31
32
32
- void remove_virtual_function (
33
+ goto_programt::targett remove_virtual_function (
33
34
goto_programt &goto_program,
34
35
goto_programt::targett target,
35
36
const dispatch_table_entriest &functions,
@@ -43,7 +44,7 @@ class remove_virtual_functionst
43
44
44
45
const class_hierarchyt &class_hierarchy;
45
46
46
- void remove_virtual_function (
47
+ goto_programt::targett remove_virtual_function (
47
48
goto_programt &goto_program,
48
49
goto_programt::targett target);
49
50
typedef std::function<
@@ -71,7 +72,7 @@ remove_virtual_functionst::remove_virtual_functionst(
71
72
{
72
73
}
73
74
74
- void remove_virtual_functionst::remove_virtual_function (
75
+ goto_programt::targett remove_virtual_functionst::remove_virtual_function (
75
76
goto_programt &goto_program,
76
77
goto_programt::targett target)
77
78
{
@@ -89,7 +90,7 @@ void remove_virtual_functionst::remove_virtual_function(
89
90
dispatch_table_entriest functions;
90
91
get_functions (function, functions);
91
92
92
- remove_virtual_function (
93
+ return remove_virtual_function (
93
94
goto_program,
94
95
target,
95
96
functions,
@@ -118,7 +119,7 @@ static void create_static_function_call(
118
119
call.arguments ()[0 ].make_typecast (need_type);
119
120
}
120
121
121
- void remove_virtual_functionst::remove_virtual_function (
122
+ goto_programt::targett remove_virtual_functionst::remove_virtual_function (
122
123
goto_programt &goto_program,
123
124
goto_programt::targett target,
124
125
const dispatch_table_entriest &functions,
@@ -130,24 +131,30 @@ void remove_virtual_functionst::remove_virtual_function(
130
131
const code_function_callt &code=
131
132
to_code_function_call (target->code );
132
133
134
+ goto_programt::targett next_target = std::next (target);
135
+
133
136
if (functions.empty ())
134
137
{
135
138
target->make_skip ();
136
- return ; // give up
139
+ remove_skip (goto_program, target, next_target);
140
+ return next_target; // give up
137
141
}
138
142
139
143
// only one option?
140
144
if (functions.size ()==1 &&
141
145
fallback_action==virtual_dispatch_fallback_actiont::CALL_LAST_FUNCTION)
142
146
{
143
147
if (functions.begin ()->symbol_expr ==symbol_exprt ())
148
+ {
144
149
target->make_skip ();
150
+ remove_skip (goto_program, target, next_target);
151
+ }
145
152
else
146
153
{
147
154
create_static_function_call (
148
155
to_code_function_call (target->code ), functions.front ().symbol_expr , ns);
149
156
}
150
- return ;
157
+ return next_target ;
151
158
}
152
159
153
160
const auto &vcall_source_loc=target->source_location ;
@@ -281,13 +288,15 @@ void remove_virtual_functionst::remove_virtual_function(
281
288
it->source_location .set_comment (comment);
282
289
}
283
290
284
- goto_programt::targett next_target=target;
285
- next_target++;
286
-
287
291
goto_program.destructive_insert (next_target, new_code);
288
292
289
293
// finally, kill original invocation
290
294
target->make_skip ();
295
+
296
+ // only remove skips within the virtual-function handling block
297
+ remove_skip (goto_program, target, next_target);
298
+
299
+ return next_target;
291
300
}
292
301
293
302
// / Used by get_functions to track the most-derived parent that provides an
@@ -475,23 +484,29 @@ bool remove_virtual_functionst::remove_virtual_functions(
475
484
{
476
485
bool did_something=false ;
477
486
478
- Forall_goto_program_instructions (target, goto_program)
487
+ for (goto_programt::instructionst::iterator
488
+ target = goto_program.instructions .begin ();
489
+ target != goto_program.instructions .end ();
490
+ ) // remove_virtual_function returns the next instruction to process
491
+ {
479
492
if (target->is_function_call ())
480
493
{
481
494
const code_function_callt &code=
482
495
to_code_function_call (target->code );
483
496
484
497
if (code.function ().id ()==ID_virtual_function)
485
498
{
486
- remove_virtual_function (goto_program, target);
499
+ target = remove_virtual_function (goto_program, target);
487
500
did_something=true ;
501
+ continue ;
488
502
}
489
503
}
490
504
505
+ ++target;
506
+ }
507
+
491
508
if (did_something)
492
- {
493
509
goto_program.update ();
494
- }
495
510
496
511
return did_something;
497
512
}
@@ -539,7 +554,7 @@ void remove_virtual_functions(goto_model_functiont &function)
539
554
rvf.remove_virtual_functions (function.get_goto_function ().body );
540
555
}
541
556
542
- void remove_virtual_function (
557
+ goto_programt::targett remove_virtual_function (
543
558
symbol_tablet &symbol_table,
544
559
goto_programt &goto_program,
545
560
goto_programt::targett instruction,
@@ -550,18 +565,22 @@ void remove_virtual_function(
550
565
class_hierarchy (symbol_table);
551
566
remove_virtual_functionst rvf (symbol_table, class_hierarchy);
552
567
553
- rvf.remove_virtual_function (
568
+ goto_programt::targett next = rvf.remove_virtual_function (
554
569
goto_program, instruction, dispatch_table, fallback_action);
570
+
571
+ goto_program.update ();
572
+
573
+ return next;
555
574
}
556
575
557
- void remove_virtual_function (
576
+ goto_programt::targett remove_virtual_function (
558
577
goto_modelt &goto_model,
559
578
goto_programt &goto_program,
560
579
goto_programt::targett instruction,
561
580
const dispatch_table_entriest &dispatch_table,
562
581
virtual_dispatch_fallback_actiont fallback_action)
563
582
{
564
- remove_virtual_function (
583
+ return remove_virtual_function (
565
584
goto_model.symbol_table ,
566
585
goto_program,
567
586
instruction,
0 commit comments