Skip to content

Commit 13dfd5a

Browse files
committed
make_binary is not safe to use when types are mixed
Removed use of make_binary in pointer contexts, as pointer arithmetic yields expressions that include pointer and non-pointer type operands, with the overall expression type being that of the pointer.
1 parent 29af567 commit 13dfd5a

File tree

4 files changed

+21
-7
lines changed

4 files changed

+21
-7
lines changed

src/analyses/local_bitvector_analysis.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,9 @@ local_bitvector_analysist::flagst local_bitvector_analysist::get_rec(
253253
{
254254
if(rhs.operands().size()>=3)
255255
{
256-
return get_rec(make_binary(rhs), loc_info_src);
256+
assert(rhs.op0().type().id()==ID_pointer);
257+
return get_rec(rhs.op0(), loc_info_src) |
258+
flagst::mk_uses_offset();
257259
}
258260
else if(rhs.operands().size()==2)
259261
{

src/analyses/local_may_alias.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ Author: Daniel Kroening, [email protected]
1212
#include <util/arith_tools.h>
1313
#include <util/std_expr.h>
1414
#include <util/std_code.h>
15-
#include <util/expr_util.h>
1615

1716
#include <ansi-c/c_types.h>
1817
#include <langapi/language_util.h>
@@ -309,7 +308,8 @@ void local_may_aliast::get_rec(
309308
{
310309
if(rhs.operands().size()>=3)
311310
{
312-
get_rec(dest, make_binary(rhs), loc_info_src);
311+
assert(rhs.op0().type().id()==ID_pointer);
312+
get_rec(dest, rhs.op0(), loc_info_src);
313313
}
314314
else if(rhs.operands().size()==2)
315315
{

src/pointer-analysis/dereference.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ Author: Daniel Kroening, [email protected]
1414
#endif
1515

1616
#include <util/std_expr.h>
17-
#include <util/expr_util.h>
1817
#include <util/byte_operators.h>
1918
#include <util/pointer_offset_size.h>
2019
#include <util/base_type.h>
@@ -279,11 +278,18 @@ exprt dereferencet::dereference_plus(
279278
const exprt &offset,
280279
const typet &type)
281280
{
281+
exprt pointer=expr.op0();
282+
exprt integer=expr.op1();
283+
284+
// need not be binary
282285
if(expr.operands().size()>2)
283-
return dereference_rec(make_binary(expr), offset, type);
286+
{
287+
assert(expr.op0().type().id()==ID_pointer);
284288

285-
// binary
286-
exprt pointer=expr.op0(), integer=expr.op1();
289+
exprt::operandst plus_ops(
290+
++expr.operands().begin(), expr.operands().end());
291+
integer.operands().swap(plus_ops);
292+
}
287293

288294
if(ns.follow(integer.type()).id()==ID_pointer)
289295
std::swap(pointer, integer);

src/util/expr_util.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,19 @@ exprt make_binary(const exprt &expr)
5555
if(operands.size()<=2)
5656
return expr;
5757

58+
// types must be identical for make_binary to be safe to use
59+
const typet &type=expr.type();
60+
5861
exprt previous=operands.front();
62+
assert(previous.type()==type);
5963

6064
for(exprt::operandst::const_iterator
6165
it=++operands.begin();
6266
it!=operands.end();
6367
++it)
6468
{
69+
assert(it->type()==type);
70+
6571
exprt tmp=expr;
6672
tmp.operands().clear();
6773
tmp.operands().resize(2);

0 commit comments

Comments
 (0)