Skip to content

Commit e5e026d

Browse files
committed
Implement l2_rename_rvalues(lvalue)
This renames the rvalue components of an lvalue expression to L2, such as the index of an array expression or the offset involved in byte-extract operation. Lvalue components (e.g. symbols) are left alone.
1 parent 7932fdd commit e5e026d

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

src/goto-symex/goto_symex_state.cpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Author: Daniel Kroening, [email protected]
1717

1818
#include <util/as_const.h>
1919
#include <util/base_exceptions.h>
20+
#include <util/byte_operators.h>
2021
#include <util/exception_utils.h>
2122
#include <util/expr_util.h>
2223
#include <util/format.h>
@@ -260,6 +261,73 @@ goto_symex_statet::rename(exprt expr, const namespacet &ns)
260261
}
261262
}
262263

264+
exprt goto_symex_statet::l2_rename_rvalues(exprt lvalue, const namespacet &ns)
265+
{
266+
rename(lvalue.type(), irep_idt(), ns);
267+
268+
if(lvalue.id() == ID_symbol)
269+
{
270+
// Nothing to do
271+
}
272+
else if(is_read_only_object(lvalue))
273+
{
274+
// Ignore apparent writes to 'NULL-object' and similar read-only objects
275+
}
276+
else if(lvalue.id() == ID_typecast)
277+
{
278+
auto &typecast_lvalue = to_typecast_expr(lvalue);
279+
typecast_lvalue.op() = l2_rename_rvalues(typecast_lvalue.op(), ns);
280+
}
281+
else if(lvalue.id() == ID_member)
282+
{
283+
auto &member_lvalue = to_member_expr(lvalue);
284+
member_lvalue.compound() = l2_rename_rvalues(member_lvalue.compound(), ns);
285+
}
286+
else if(lvalue.id() == ID_index)
287+
{
288+
// The index is an rvalue:
289+
auto &index_lvalue = to_index_expr(lvalue);
290+
index_lvalue.array() = l2_rename_rvalues(index_lvalue.array(), ns);
291+
index_lvalue.index() = rename(index_lvalue.index(), ns).get();
292+
}
293+
else if(
294+
lvalue.id() == ID_byte_extract_little_endian ||
295+
lvalue.id() == ID_byte_extract_big_endian)
296+
{
297+
// The offset is an rvalue:
298+
auto &byte_extract_lvalue = to_byte_extract_expr(lvalue);
299+
byte_extract_lvalue.op() = l2_rename_rvalues(byte_extract_lvalue.op(), ns);
300+
byte_extract_lvalue.offset() = rename(byte_extract_lvalue.offset(), ns);
301+
}
302+
else if(lvalue.id() == ID_if)
303+
{
304+
// The condition is an rvalue:
305+
auto &if_lvalue = to_if_expr(lvalue);
306+
if_lvalue.cond() = rename(if_lvalue.cond(), ns);
307+
if(!if_lvalue.cond().is_false())
308+
if_lvalue.true_case() = l2_rename_rvalues(if_lvalue.true_case(), ns);
309+
if(!if_lvalue.cond().is_true())
310+
if_lvalue.false_case() = l2_rename_rvalues(if_lvalue.false_case(), ns);
311+
}
312+
else if(lvalue.id() == ID_complex_real)
313+
{
314+
auto &complex_real_lvalue = to_complex_real_expr(lvalue);
315+
complex_real_lvalue.op() = l2_rename_rvalues(complex_real_lvalue.op(), ns);
316+
}
317+
else if(lvalue.id() == ID_complex_imag)
318+
{
319+
auto &complex_imag_lvalue = to_complex_imag_expr(lvalue);
320+
complex_imag_lvalue.op() = l2_rename_rvalues(complex_imag_lvalue.op(), ns);
321+
}
322+
else
323+
{
324+
throw unsupported_operation_exceptiont(
325+
"l2_rename_rvalues case `" + lvalue.id_string() + "' not handled");
326+
}
327+
328+
return lvalue;
329+
}
330+
263331
template renamedt<exprt, L1>
264332
goto_symex_statet::rename<L1>(exprt expr, const namespacet &ns);
265333

src/goto-symex/goto_symex_state.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ class goto_symex_statet final : public goto_statet
107107
template <levelt level = L2>
108108
void rename(typet &type, const irep_idt &l1_identifier, const namespacet &ns);
109109

110+
exprt l2_rename_rvalues(exprt lvalue, const namespacet &ns);
111+
110112
/// \return lhs renamed to level 2
111113
renamedt<ssa_exprt, L2> assignment(
112114
ssa_exprt lhs, // L0/L1

0 commit comments

Comments
 (0)