Skip to content

Commit fad93bc

Browse files
committed
replace_symbolt must consider all non-lvalues
Literal constants are not the only ones: for example, address-of isn't an lvalue either. Make is_lvalue globally available to accomplish this.
1 parent db85d79 commit fad93bc

File tree

5 files changed

+27
-16
lines changed

5 files changed

+27
-16
lines changed

src/goto-programs/builtin_functions.cpp

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Author: Daniel Kroening, [email protected]
1616
#include <util/arith_tools.h>
1717
#include <util/c_types.h>
1818
#include <util/cprover_prefix.h>
19+
#include <util/expr_util.h>
1920
#include <util/pointer_offset_size.h>
2021
#include <util/rational.h>
2122
#include <util/rational_tools.h>
@@ -621,20 +622,6 @@ void goto_convertt::do_array_op(
621622
copy(array_op_statement, OTHER, dest);
622623
}
623624

624-
bool is_lvalue(const exprt &expr)
625-
{
626-
if(expr.id()==ID_index)
627-
return is_lvalue(to_index_expr(expr).op0());
628-
else if(expr.id()==ID_member)
629-
return is_lvalue(to_member_expr(expr).op0());
630-
else if(expr.id()==ID_dereference)
631-
return true;
632-
else if(expr.id()==ID_symbol)
633-
return true;
634-
else
635-
return false;
636-
}
637-
638625
exprt make_va_list(const exprt &expr)
639626
{
640627
// we first strip any typecast

src/util/expr_util.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,3 +201,18 @@ if_exprt lift_if(const exprt &src, std::size_t operand_number)
201201

202202
return result;
203203
}
204+
205+
/// returns true if the expression can be used as an lvalue
206+
bool is_lvalue(const exprt &expr)
207+
{
208+
if(expr.id() == ID_index)
209+
return is_lvalue(to_index_expr(expr).op0());
210+
else if(expr.id() == ID_member)
211+
return is_lvalue(to_member_expr(expr).op0());
212+
else if(expr.id() == ID_dereference)
213+
return true;
214+
else if(expr.id() == ID_symbol)
215+
return true;
216+
else
217+
return false;
218+
}

src/util/expr_util.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,6 @@ bool has_subtype(const typet &, const irep_idt &id, const namespacet &);
7272
/// lift up an if_exprt one level
7373
if_exprt lift_if(const exprt &, std::size_t operand_number);
7474

75+
bool is_lvalue(const exprt &);
76+
7577
#endif // CPROVER_UTIL_EXPR_UTIL_H

src/util/replace_symbol.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ Author: Daniel Kroening, [email protected]
88

99
#include "replace_symbol.h"
1010

11-
#include "std_types.h"
11+
#include "expr_util.h"
1212
#include "std_expr.h"
13+
#include "std_types.h"
1314

1415
replace_symbolt::replace_symbolt()
1516
{
@@ -80,7 +81,7 @@ bool replace_symbolt::replace(
8081
{
8182
const exprt &e=it->second;
8283

83-
if(!replace_with_const && e.is_constant()) // Would give non l-value.
84+
if(!replace_with_const && !is_lvalue(e))
8485
return true;
8586

8687
dest=e;

unit/util/replace_symbol.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,10 @@ TEST_CASE("Lvalue only", "[core][util][optional]")
5151

5252
REQUIRE(r.replace(binary) == true);
5353
REQUIRE(binary.op0() == address_of_exprt(s1));
54+
55+
address_of_exprt address_of(s1);
56+
r.insert("b", address_of);
57+
58+
REQUIRE(r.replace(binary) == true);
59+
REQUIRE(binary.op1() == address_of_exprt(s2));
5460
}

0 commit comments

Comments
 (0)