@@ -163,11 +163,11 @@ void goto_symex_statet::assignment(
163
163
bool allow_pointer_unsoundness)
164
164
{
165
165
// identifier should be l0 or l1, make sure it's l1
166
- rename ( lhs, ns, L1 );
166
+ lhs = rename_ssa<L1>( std::move ( lhs) , ns);
167
167
irep_idt l1_identifier=lhs.get_identifier ();
168
168
169
169
// the type might need renaming
170
- rename (lhs.type (), l1_identifier, ns);
170
+ rename <L2> (lhs.type (), l1_identifier, ns);
171
171
lhs.update_type ();
172
172
if (run_validation_checks)
173
173
{
@@ -263,10 +263,31 @@ void goto_symex_statet::set_l2_indices(
263
263
ssa_expr.set_level_2 (level2.current_count (ssa_expr.get_identifier ()));
264
264
}
265
265
266
- void goto_symex_statet::rename (
267
- exprt &expr,
268
- const namespacet &ns,
269
- levelt level)
266
+ template <goto_symex_statet::levelt level>
267
+ ssa_exprt goto_symex_statet::rename_ssa (ssa_exprt ssa, const namespacet &ns)
268
+ {
269
+ static_assert (
270
+ level == L0 || level == L1,
271
+ " rename_ssa can only be used for levels L0 and L1" );
272
+ if (level == L0)
273
+ set_l0_indices (ssa, ns);
274
+ else if (level == L1)
275
+ set_l1_indices (ssa, ns);
276
+ else
277
+ UNREACHABLE;
278
+
279
+ rename <level>(ssa.type (), ssa.get_identifier (), ns);
280
+ ssa.update_type ();
281
+ return ssa;
282
+ }
283
+
284
+ // / Ensure `rename_ssa` gets compiled for L0
285
+ template ssa_exprt goto_symex_statet::rename_ssa<goto_symex_statet::L0>(
286
+ ssa_exprt ssa,
287
+ const namespacet &ns);
288
+
289
+ template <goto_symex_statet::levelt level>
290
+ exprt goto_symex_statet::rename (exprt expr, const namespacet &ns)
270
291
{
271
292
// rename all the symbols with their last known value
272
293
@@ -277,20 +298,16 @@ void goto_symex_statet::rename(
277
298
278
299
if (level == L0)
279
300
{
280
- set_l0_indices (ssa, ns);
281
- rename (expr.type (), ssa.get_identifier (), ns, level);
282
- ssa.update_type ();
301
+ ssa = rename_ssa<L0>(std::move (ssa), ns);
283
302
}
284
303
else if (level == L1)
285
304
{
286
- set_l1_indices (ssa, ns);
287
- rename (expr.type (), ssa.get_identifier (), ns, level);
288
- ssa.update_type ();
305
+ ssa = rename_ssa<L1>(std::move (ssa), ns);
289
306
}
290
307
else if (level==L2)
291
308
{
292
309
set_l1_indices (ssa, ns);
293
- rename (expr.type (), ssa.get_identifier (), ns, level );
310
+ rename <level> (expr.type (), ssa.get_identifier (), ns);
294
311
ssa.update_type ();
295
312
296
313
if (l2_thread_read_encoding (ssa, ns))
@@ -318,33 +335,24 @@ void goto_symex_statet::rename(
318
335
{
319
336
// we never rename function symbols
320
337
if (as_const (expr).type ().id () == ID_code)
321
- {
322
- rename (
323
- expr.type (),
324
- to_symbol_expr (expr).get_identifier (),
325
- ns,
326
- level);
327
-
328
- return ;
329
- }
330
-
331
- expr=ssa_exprt (expr);
332
- rename (expr, ns, level);
338
+ rename <level>(expr.type (), to_symbol_expr (expr).get_identifier (), ns);
339
+ else
340
+ expr = rename <level>(ssa_exprt{expr}, ns);
333
341
}
334
342
else if (expr.id ()==ID_address_of)
335
343
{
336
344
auto &address_of_expr = to_address_of_expr (expr);
337
- rename_address (address_of_expr.object (), ns, level );
345
+ rename_address<level> (address_of_expr.object (), ns);
338
346
to_pointer_type (expr.type ()).subtype () =
339
347
as_const (address_of_expr).object ().type ();
340
348
}
341
349
else
342
350
{
343
- rename (expr.type (), irep_idt (), ns, level );
351
+ rename <level> (expr.type (), irep_idt (), ns);
344
352
345
353
// do this recursively
346
354
Forall_operands (it, expr)
347
- rename ( *it, ns, level );
355
+ *it = rename <level>( std::move ( *it) , ns);
348
356
349
357
const exprt &c_expr = as_const (expr);
350
358
INVARIANT (
@@ -356,6 +364,7 @@ void goto_symex_statet::rename(
356
364
" Type of renamed expr should be the same as operands for with_exprt and "
357
365
" if_exprt" );
358
366
}
367
+ return expr;
359
368
}
360
369
361
370
// / thread encoding
@@ -535,10 +544,8 @@ bool goto_symex_statet::l2_thread_write_encoding(
535
544
return threads.size ()>1 ;
536
545
}
537
546
538
- void goto_symex_statet::rename_address (
539
- exprt &expr,
540
- const namespacet &ns,
541
- levelt level)
547
+ template <goto_symex_statet::levelt level>
548
+ void goto_symex_statet::rename_address (exprt &expr, const namespacet &ns)
542
549
{
543
550
if (expr.id ()==ID_symbol &&
544
551
expr.get_bool (ID_C_SSA_symbol))
@@ -548,42 +555,42 @@ void goto_symex_statet::rename_address(
548
555
// only do L1!
549
556
set_l1_indices (ssa, ns);
550
557
551
- rename (expr.type (), ssa.get_identifier (), ns, level );
558
+ rename <level> (expr.type (), ssa.get_identifier (), ns);
552
559
ssa.update_type ();
553
560
}
554
561
else if (expr.id ()==ID_symbol)
555
562
{
556
563
expr=ssa_exprt (expr);
557
- rename_address (expr, ns, level );
564
+ rename_address<level> (expr, ns);
558
565
}
559
566
else
560
567
{
561
568
if (expr.id ()==ID_index)
562
569
{
563
570
index_exprt &index_expr=to_index_expr (expr);
564
571
565
- rename_address (index_expr.array (), ns, level );
572
+ rename_address<level> (index_expr.array (), ns);
566
573
PRECONDITION (index_expr.array ().type ().id () == ID_array);
567
574
expr.type () = to_array_type (index_expr.array ().type ()).subtype ();
568
575
569
576
// the index is not an address
570
- rename ( index_expr.index (), ns, level );
577
+ index_expr. index () = rename <level>( std::move ( index_expr.index ()) , ns);
571
578
}
572
579
else if (expr.id ()==ID_if)
573
580
{
574
581
// the condition is not an address
575
582
if_exprt &if_expr=to_if_expr (expr);
576
- rename ( if_expr.cond (), ns, level );
577
- rename_address (if_expr.true_case (), ns, level );
578
- rename_address (if_expr.false_case (), ns, level );
583
+ if_expr. cond () = rename <level>( std::move ( if_expr.cond ()) , ns);
584
+ rename_address<level> (if_expr.true_case (), ns);
585
+ rename_address<level> (if_expr.false_case (), ns);
579
586
580
587
if_expr.type ()=if_expr.true_case ().type ();
581
588
}
582
589
else if (expr.id ()==ID_member)
583
590
{
584
591
member_exprt &member_expr=to_member_expr (expr);
585
592
586
- rename_address (member_expr.struct_op (), ns, level );
593
+ rename_address<level> (member_expr.struct_op (), ns);
587
594
588
595
// type might not have been renamed in case of nesting of
589
596
// structs and pointers/arrays
@@ -600,17 +607,17 @@ void goto_symex_statet::rename_address(
600
607
expr.type ()=comp.type ();
601
608
}
602
609
else
603
- rename (expr.type (), irep_idt (), ns, level );
610
+ rename <level> (expr.type (), irep_idt (), ns);
604
611
}
605
612
else
606
613
{
607
614
// this could go wrong, but we would have to re-typecheck ...
608
- rename (expr.type (), irep_idt (), ns, level );
615
+ rename <level> (expr.type (), irep_idt (), ns);
609
616
610
617
// do this recursively; we assume here
611
618
// that all the operands are addresses
612
619
Forall_operands (it, expr)
613
- rename_address (*it, ns, level );
620
+ rename_address<level> (*it, ns);
614
621
}
615
622
}
616
623
}
@@ -668,11 +675,11 @@ static bool requires_renaming(const typet &type, const namespacet &ns)
668
675
return false ;
669
676
}
670
677
678
+ template <goto_symex_statet::levelt level>
671
679
void goto_symex_statet::rename (
672
680
typet &type,
673
681
const irep_idt &l1_identifier,
674
- const namespacet &ns,
675
- levelt level)
682
+ const namespacet &ns)
676
683
{
677
684
// check whether there are symbol expressions in the type; if not, there
678
685
// is no need to expand the struct/union tags in the type
@@ -711,8 +718,8 @@ void goto_symex_statet::rename(
711
718
if (type.id ()==ID_array)
712
719
{
713
720
auto &array_type = to_array_type (type);
714
- rename (array_type.subtype (), irep_idt (), ns, level );
715
- rename ( array_type.size (), ns, level );
721
+ rename <level> (array_type.subtype (), irep_idt (), ns);
722
+ array_type. size () = rename <level>( std::move ( array_type.size ()) , ns);
716
723
}
717
724
else if (type.id () == ID_struct || type.id () == ID_union)
718
725
{
@@ -723,14 +730,17 @@ void goto_symex_statet::rename(
723
730
{
724
731
// be careful, or it might get cyclic
725
732
if (component.type ().id () == ID_array)
726
- rename (to_array_type (component.type ()).size (), ns, level);
733
+ {
734
+ auto &array_type = to_array_type (component.type ());
735
+ array_type.size () = rename <level>(std::move (array_type.size ()), ns);
736
+ }
727
737
else if (component.type ().id () != ID_pointer)
728
- rename (component.type (), irep_idt (), ns, level );
738
+ rename <level> (component.type (), irep_idt (), ns);
729
739
}
730
740
}
731
741
else if (type.id ()==ID_pointer)
732
742
{
733
- rename (to_pointer_type (type).subtype (), irep_idt (), ns, level );
743
+ rename <level> (to_pointer_type (type).subtype (), irep_idt (), ns);
734
744
}
735
745
736
746
if (level==L2 &&
0 commit comments