@@ -54,7 +54,7 @@ class remove_virtual_functionst
54
54
function_call_resolvert;
55
55
void get_child_functions_rec (
56
56
const irep_idt &,
57
- const symbol_exprt &,
57
+ const optionalt< symbol_exprt> &,
58
58
const irep_idt &,
59
59
dispatch_table_entriest &,
60
60
dispatch_table_entries_mapt &,
@@ -166,15 +166,17 @@ goto_programt::targett remove_virtual_functionst::remove_virtual_function(
166
166
if (functions.size ()==1 &&
167
167
fallback_action==virtual_dispatch_fallback_actiont::CALL_LAST_FUNCTION)
168
168
{
169
- if (functions.begin ()-> symbol_expr == symbol_exprt ())
169
+ if (! functions.front (). symbol_expr . has_value ())
170
170
{
171
171
target->make_skip ();
172
172
remove_skip (goto_program, target, next_target);
173
173
}
174
174
else
175
175
{
176
176
create_static_function_call (
177
- to_code_function_call (target->code ), functions.front ().symbol_expr , ns);
177
+ to_code_function_call (target->code ),
178
+ *functions.front ().symbol_expr ,
179
+ ns);
178
180
}
179
181
return next_target;
180
182
}
@@ -195,7 +197,6 @@ goto_programt::targett remove_virtual_functionst::remove_virtual_function(
195
197
goto_programt new_code_gotos;
196
198
197
199
exprt this_expr=code.arguments ()[0 ];
198
- const auto &last_function_symbol=functions.back ().symbol_expr ;
199
200
200
201
const typet &this_type=this_expr.type ();
201
202
INVARIANT (this_type.id () == ID_pointer, " this parameter must be a pointer" );
@@ -219,26 +220,29 @@ goto_programt::targett remove_virtual_functionst::remove_virtual_function(
219
220
220
221
// get initial identifier for grouping
221
222
INVARIANT (!functions.empty (), " Function dispatch table cannot be empty." );
223
+ const auto &last_function_symbol = functions.back ().symbol_expr ;
222
224
223
225
std::map<irep_idt, goto_programt::targett> calls;
224
226
// Note backwards iteration, to get the fallback candidate first.
225
227
for (auto it=functions.crbegin (), itend=functions.crend (); it!=itend; ++it)
226
228
{
227
229
const auto &fun=*it;
228
- auto insertit=calls.insert (
229
- {fun.symbol_expr .get_identifier (), goto_programt::targett ()});
230
+ irep_idt id_or_empty = fun.symbol_expr .has_value ()
231
+ ? fun.symbol_expr ->get_identifier ()
232
+ : irep_idt ();
233
+ auto insertit = calls.insert ({id_or_empty, goto_programt::targett ()});
230
234
231
235
// Only create one call sequence per possible target:
232
236
if (insertit.second )
233
237
{
234
238
goto_programt::targett t1=new_code_calls.add_instruction ();
235
239
t1->source_location =vcall_source_loc;
236
- if (! fun.symbol_expr .get_identifier (). empty ())
240
+ if (fun.symbol_expr .has_value ())
237
241
{
238
242
// call function
239
243
t1->make_function_call (code);
240
244
create_static_function_call (
241
- to_code_function_call (t1->code ), fun.symbol_expr , ns);
245
+ to_code_function_call (t1->code ), * fun.symbol_expr , ns);
242
246
}
243
247
else
244
248
{
@@ -257,9 +261,12 @@ goto_programt::targett remove_virtual_functionst::remove_virtual_function(
257
261
}
258
262
259
263
// Fall through to the default callee if possible:
260
- if (fallback_action ==
261
- virtual_dispatch_fallback_actiont::CALL_LAST_FUNCTION &&
262
- fun.symbol_expr == last_function_symbol)
264
+ if (
265
+ fallback_action ==
266
+ virtual_dispatch_fallback_actiont::CALL_LAST_FUNCTION &&
267
+ fun.symbol_expr .has_value () == last_function_symbol.has_value () &&
268
+ (!fun.symbol_expr .has_value () ||
269
+ *fun.symbol_expr == *last_function_symbol))
263
270
{
264
271
// Nothing to do
265
272
}
@@ -271,8 +278,11 @@ goto_programt::targett remove_virtual_functionst::remove_virtual_function(
271
278
272
279
// If the previous GOTO goes to the same callee, join it
273
280
// (e.g. turning IF x GOTO y into IF x || z GOTO y)
274
- if (it != functions.crbegin () &&
275
- std::prev (it)->symbol_expr == fun.symbol_expr )
281
+ if (
282
+ it != functions.crbegin () &&
283
+ std::prev (it)->symbol_expr .has_value () == fun.symbol_expr .has_value () &&
284
+ (!fun.symbol_expr .has_value () ||
285
+ *(std::prev (it)->symbol_expr ) == *fun.symbol_expr ))
276
286
{
277
287
INVARIANT (
278
288
!new_code_gotos.empty (),
@@ -337,7 +347,7 @@ goto_programt::targett remove_virtual_functionst::remove_virtual_function(
337
347
// / \param resolve_function_call`: function to resolve abstract method call
338
348
void remove_virtual_functionst::get_child_functions_rec (
339
349
const irep_idt &this_id,
340
- const symbol_exprt &last_method_defn,
350
+ const optionalt< symbol_exprt> &last_method_defn,
341
351
const irep_idt &component_name,
342
352
dispatch_table_entriest &functions,
343
353
dispatch_table_entries_mapt &entry_map,
@@ -354,9 +364,10 @@ void remove_virtual_functionst::get_child_functions_rec(
354
364
auto it = entry_map.find (child);
355
365
if (
356
366
it != entry_map.end () &&
357
- !has_prefix (
358
- id2string (it->second .symbol_expr .get_identifier ()),
359
- " java::java.lang.Object" ))
367
+ (!it->second .symbol_expr .has_value () ||
368
+ !has_prefix (
369
+ id2string (it->second .symbol_expr ->get_identifier ()),
370
+ " java::java.lang.Object" )))
360
371
{
361
372
continue ;
362
373
}
@@ -365,13 +376,13 @@ void remove_virtual_functionst::get_child_functions_rec(
365
376
if (method.is_not_nil ())
366
377
{
367
378
function.symbol_expr =to_symbol_expr (method);
368
- function.symbol_expr . set (ID_C_class, child);
379
+ function.symbol_expr -> set (ID_C_class, child);
369
380
}
370
381
else
371
382
{
372
383
function.symbol_expr =last_method_defn;
373
384
}
374
- if (function.symbol_expr == symbol_exprt ())
385
+ if (! function.symbol_expr . has_value ())
375
386
{
376
387
const resolve_inherited_componentt::inherited_componentt
377
388
&resolved_call = resolve_function_call (child, component_name);
@@ -383,12 +394,12 @@ void remove_virtual_functionst::get_child_functions_rec(
383
394
resolved_call.get_full_component_identifier ());
384
395
385
396
function.symbol_expr = called_symbol.symbol_expr ();
386
- function.symbol_expr . set (
397
+ function.symbol_expr -> set (
387
398
ID_C_class, resolved_call.get_class_identifier ());
388
399
}
389
400
}
390
401
functions.push_back (function);
391
- entry_map.insert ({ child, function} );
402
+ entry_map.emplace ( child, function);
392
403
393
404
get_child_functions_rec (
394
405
child,
@@ -426,7 +437,8 @@ void remove_virtual_functionst::get_functions(
426
437
const resolve_inherited_componentt::inherited_componentt
427
438
&resolved_call = get_virtual_call_target (class_id, function_name, false );
428
439
429
- dispatch_table_entryt root_function;
440
+ // might be an abstract function
441
+ dispatch_table_entryt root_function (class_id);
430
442
431
443
if (resolved_call.is_valid ())
432
444
{
@@ -436,14 +448,9 @@ void remove_virtual_functionst::get_functions(
436
448
symbol_table.lookup_ref (resolved_call.get_full_component_identifier ());
437
449
438
450
root_function.symbol_expr =called_symbol.symbol_expr ();
439
- root_function.symbol_expr . set (
451
+ root_function.symbol_expr -> set (
440
452
ID_C_class, resolved_call.get_class_identifier ());
441
453
}
442
- else
443
- {
444
- // No definition here; this is an abstract function.
445
- root_function.class_id =class_id;
446
- }
447
454
448
455
// iterate over all children, transitively
449
456
dispatch_table_entries_mapt entry_map;
@@ -455,7 +462,7 @@ void remove_virtual_functionst::get_functions(
455
462
entry_map,
456
463
resolve_function_call);
457
464
458
- if (root_function.symbol_expr != symbol_exprt ())
465
+ if (root_function.symbol_expr . has_value ())
459
466
functions.push_back (root_function);
460
467
461
468
// Sort for the identifier of the function call symbol expression, grouping
@@ -465,20 +472,21 @@ void remove_virtual_functionst::get_functions(
465
472
std::sort (
466
473
functions.begin (),
467
474
functions.end (),
468
- [](const dispatch_table_entryt &a, dispatch_table_entryt &b)
469
- {
470
- if (
471
- has_prefix (
472
- id2string (a.symbol_expr .get_identifier ()), " java::java.lang.Object" ))
475
+ [](const dispatch_table_entryt &a, const dispatch_table_entryt &b) {
476
+ irep_idt a_id = a.symbol_expr .has_value ()
477
+ ? a.symbol_expr ->get_identifier ()
478
+ : irep_idt ();
479
+ irep_idt b_id = b.symbol_expr .has_value ()
480
+ ? b.symbol_expr ->get_identifier ()
481
+ : irep_idt ();
482
+
483
+ if (has_prefix (id2string (a_id), " java::java.lang.Object" ))
473
484
return false ;
474
- else if (
475
- has_prefix (
476
- id2string (b.symbol_expr .get_identifier ()), " java::java.lang.Object" ))
485
+ else if (has_prefix (id2string (b_id), " java::java.lang.Object" ))
477
486
return true ;
478
487
else
479
488
{
480
- int cmp = a.symbol_expr .get_identifier ().compare (
481
- b.symbol_expr .get_identifier ());
489
+ int cmp = a_id.compare (b_id);
482
490
if (cmp == 0 )
483
491
return a.class_id < b.class_id ;
484
492
else
0 commit comments