|
15 | 15 | #include <util/config.h>
|
16 | 16 | #include <util/cprover_prefix.h>
|
17 | 17 | #include <util/expr_util.h>
|
| 18 | +#include <util/find_symbols.h> |
18 | 19 | #include <util/floatbv_expr.h>
|
19 | 20 | #include <util/ieee_float.h>
|
20 | 21 | #include <util/mathematical_expr.h>
|
@@ -1608,17 +1609,20 @@ void c_typecheck_baset::typecheck_expr_trinary(if_exprt &expr)
|
1608 | 1609 | exprt tmp1=simplify_expr(operands[1], *this);
|
1609 | 1610 | exprt tmp2=simplify_expr(operands[2], *this);
|
1610 | 1611 |
|
1611 |
| - // is one of them void * AND null? Convert that to the other. |
1612 |
| - // (at least that's how GCC behaves) |
| 1612 | + // Is one of them void * AND null? Convert that to the other. |
| 1613 | + // (At least that's how GCC, Clang, and Visual Studio behave. Presence of |
| 1614 | + // symbols blocks them from simplifying the expression to NULL.) |
1613 | 1615 | if(
|
1614 | 1616 | to_pointer_type(operands[1].type()).base_type().id() == ID_empty &&
|
1615 |
| - tmp1.is_constant() && is_null_pointer(to_constant_expr(tmp1))) |
| 1617 | + tmp1.is_constant() && is_null_pointer(to_constant_expr(tmp1)) && |
| 1618 | + find_symbols(operands[1]).empty()) |
1616 | 1619 | {
|
1617 | 1620 | implicit_typecast(operands[1], operands[2].type());
|
1618 | 1621 | }
|
1619 | 1622 | else if(
|
1620 | 1623 | to_pointer_type(operands[2].type()).base_type().id() == ID_empty &&
|
1621 |
| - tmp2.is_constant() && is_null_pointer(to_constant_expr(tmp2))) |
| 1624 | + tmp2.is_constant() && is_null_pointer(to_constant_expr(tmp2)) && |
| 1625 | + find_symbols(operands[2]).empty()) |
1622 | 1626 | {
|
1623 | 1627 | implicit_typecast(operands[2], operands[1].type());
|
1624 | 1628 | }
|
|
0 commit comments