@@ -282,13 +282,27 @@ goto_symex_statet::rename_ssa<L1>(ssa_exprt ssa, const namespacet &ns);
282
282
283
283
template <levelt level>
284
284
exprt goto_symex_statet::rename (exprt expr, const namespacet &ns)
285
+ {
286
+ if (auto renamed = rename_expr<level>(expr, ns))
287
+ return *renamed;
288
+ else
289
+ return expr;
290
+ }
291
+
292
+ // explicitly instantiate templates
293
+ template exprt goto_symex_statet::rename<L1>(exprt expr, const namespacet &ns);
294
+ template exprt goto_symex_statet::rename<L2>(exprt expr, const namespacet &ns);
295
+
296
+ template <levelt level>
297
+ optionalt<exprt>
298
+ goto_symex_statet::rename_expr (const exprt &expr, const namespacet &ns)
285
299
{
286
300
// rename all the symbols with their last known value
287
301
288
302
if (expr.id ()==ID_symbol &&
289
303
expr.get_bool (ID_C_SSA_symbol))
290
304
{
291
- ssa_exprt & ssa= to_ssa_expr (expr);
305
+ ssa_exprt ssa = to_ssa_expr (expr);
292
306
293
307
if (level == L0)
294
308
{
@@ -324,11 +338,13 @@ exprt goto_symex_statet::rename(exprt expr, const namespacet &ns)
324
338
auto p_it = propagation.find (ssa.get_identifier ());
325
339
326
340
if (p_it != propagation.end ())
327
- expr= p_it->second ; // already L2
341
+ return p_it->second ; // already L2
328
342
else
329
343
ssa = set_indices<L2>(std::move (ssa), ns).get ();
330
344
}
331
345
}
346
+
347
+ return std::move (ssa);
332
348
}
333
349
else if (expr.id ()==ID_symbol)
334
350
{
@@ -341,40 +357,83 @@ exprt goto_symex_statet::rename(exprt expr, const namespacet &ns)
341
357
auto renamed_type = rename_type<level>(
342
358
expr.type (), to_symbol_expr (expr).get_identifier (), ns))
343
359
{
344
- expr.type () = std::move (*renamed_type);
360
+ exprt result = expr;
361
+ result.type () = std::move (*renamed_type);
362
+ return std::move (result);
345
363
}
364
+ else
365
+ return {};
346
366
}
367
+
368
+ ssa_exprt ssa{expr};
369
+ if (auto renamed = rename_expr<level>(ssa, ns))
370
+ return renamed;
347
371
else
348
- expr = rename <level>(ssa_exprt{expr}, ns );
372
+ return std::move (ssa );
349
373
}
350
374
else if (expr.id ()==ID_address_of)
351
375
{
352
376
auto &address_of_expr = to_address_of_expr (expr);
353
377
auto renamed_object = rename_address<level>(address_of_expr.object (), ns);
354
378
355
379
if (renamed_object.has_value ())
356
- expr = address_of_exprt{std::move (*renamed_object)};
380
+ return address_of_exprt{std::move (*renamed_object)};
381
+ else
382
+ return {};
357
383
}
358
384
else
359
385
{
386
+ optionalt<exprt> result;
387
+
360
388
if (auto renamed_type = rename_type<level>(expr.type (), irep_idt (), ns))
361
389
{
362
- expr.type () = std::move (*renamed_type);
390
+ result = expr;
391
+ result->type () = std::move (*renamed_type);
363
392
}
364
393
365
394
// do this recursively
366
- Forall_operands (it, expr)
367
- *it = rename <level>(std::move (*it), ns);
368
-
369
- const exprt &c_expr = as_const (expr);
370
- INVARIANT (
371
- (expr.id () != ID_with ||
372
- c_expr.type () == to_with_expr (c_expr).old ().type ()) &&
373
- (expr.id () != ID_if ||
374
- (c_expr.type () == to_if_expr (c_expr).true_case ().type () &&
375
- c_expr.type () == to_if_expr (c_expr).false_case ().type ())),
376
- " Type of renamed expr should be the same as operands for with_exprt and "
377
- " if_exprt" );
395
+ optionalt<exprt::operandst> result_operands;
396
+ std::size_t op_index = 0 ;
397
+
398
+ for (auto &op : expr.operands ())
399
+ {
400
+ if (auto renamed_op = rename_expr<level>(op, ns))
401
+ {
402
+ if (!result_operands.has_value ())
403
+ result_operands = expr.operands ();
404
+
405
+ (*result_operands)[op_index] = std::move (*renamed_op);
406
+ }
407
+ ++op_index;
408
+ }
409
+
410
+ if (result_operands.has_value ())
411
+ {
412
+ if (!result.has_value ())
413
+ result = expr;
414
+
415
+ result->operands () = std::move (*result_operands);
416
+ }
417
+
418
+ if (result.has_value ())
419
+ {
420
+ const exprt &c_expr = as_const (*result);
421
+ if (expr.id () == ID_with)
422
+ {
423
+ INVARIANT (
424
+ c_expr.type () == to_with_expr (c_expr).old ().type (),
425
+ " type of renamed expr should be the same as operands for with_exprt" );
426
+ }
427
+ else if (expr.id () == ID_if)
428
+ {
429
+ INVARIANT (
430
+ c_expr.type () == to_if_expr (c_expr).true_case ().type () &&
431
+ c_expr.type () == to_if_expr (c_expr).false_case ().type (),
432
+ " type of renamed expr should be the same as operands for if_exprt" );
433
+ }
434
+ }
435
+
436
+ return result;
378
437
}
379
438
return expr;
380
439
}
@@ -588,9 +647,9 @@ goto_symex_statet::rename_address(const exprt &expr, const namespacet &ns)
588
647
auto renamed_array = rename_address<level>(index_expr.array (), ns);
589
648
590
649
// the index is not an address
591
- auto renamed_index = rename <level>(index_expr.index (), ns);
650
+ auto renamed_index = rename_expr <level>(index_expr.index (), ns);
592
651
593
- if (renamed_array.has_value () || renamed_index != index_expr. index ())
652
+ if (renamed_array.has_value () || renamed_index. has_value ())
594
653
{
595
654
index_exprt result = index_expr;
596
655
@@ -600,8 +659,8 @@ goto_symex_statet::rename_address(const exprt &expr, const namespacet &ns)
600
659
result.type () = to_array_type (result.array ().type ()).subtype ();
601
660
}
602
661
603
- if (renamed_index != index_expr. index ())
604
- result.index () = std::move (renamed_index);
662
+ if (renamed_index. has_value ())
663
+ result.index () = std::move (* renamed_index);
605
664
606
665
return std::move (result);
607
666
}
@@ -612,18 +671,18 @@ goto_symex_statet::rename_address(const exprt &expr, const namespacet &ns)
612
671
{
613
672
// the condition is not an address
614
673
const if_exprt &if_expr = to_if_expr (expr);
615
- auto renamed_cond = rename <level>(if_expr.cond (), ns);
674
+ auto renamed_cond = rename_expr <level>(if_expr.cond (), ns);
616
675
auto renamed_true = rename_address<level>(if_expr.true_case (), ns);
617
676
auto renamed_false = rename_address<level>(if_expr.false_case (), ns);
618
677
619
678
if (
620
- renamed_cond != if_expr. cond () || renamed_true.has_value () ||
679
+ renamed_cond. has_value () || renamed_true.has_value () ||
621
680
renamed_false.has_value ())
622
681
{
623
682
if_exprt result = if_expr;
624
683
625
- if (renamed_cond != if_expr. cond ())
626
- result.cond () = std::move (renamed_cond);
684
+ if (renamed_cond. has_value ())
685
+ result.cond () = std::move (* renamed_cond);
627
686
628
687
if (renamed_true.has_value ())
629
688
{
@@ -773,17 +832,17 @@ optionalt<typet> goto_symex_statet::rename_type(
773
832
auto &array_type = to_array_type (type);
774
833
auto renamed_subtype =
775
834
rename_type<level>(array_type.subtype (), irep_idt (), ns);
776
- auto renamed_size = rename <level>(array_type.size (), ns);
835
+ auto renamed_size = rename_expr <level>(array_type.size (), ns);
777
836
778
- if (renamed_subtype.has_value () || renamed_size != array_type. size ())
837
+ if (renamed_subtype.has_value () || renamed_size. has_value ())
779
838
{
780
839
array_typet result_type = array_type;
781
840
782
841
if (renamed_subtype.has_value ())
783
842
result_type.subtype () = std::move (*renamed_subtype);
784
843
785
- if (renamed_size != array_type. size ())
786
- result_type.size () = std::move (renamed_size);
844
+ if (renamed_size. has_value ())
845
+ result_type.size () = std::move (* renamed_size);
787
846
788
847
result = std::move (result_type);
789
848
}
@@ -800,11 +859,11 @@ optionalt<typet> goto_symex_statet::rename_type(
800
859
// be careful, or it might get cyclic
801
860
if (component.type ().id () == ID_array)
802
861
{
803
- auto &array_type = to_array_type (component. type ());
804
- auto renamed_expr = rename <level>(array_type. size (), ns);
805
- if (renamed_expr != array_type. size ())
862
+ if (
863
+ auto renamed_expr =
864
+ rename_expr<level>( to_array_type (component. type ()). size (), ns ))
806
865
{
807
- to_array_type (comp_it->type ()).size () = std::move (renamed_expr);
866
+ to_array_type (comp_it->type ()).size () = std::move (* renamed_expr);
808
867
modified = true ;
809
868
}
810
869
}
0 commit comments