|
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>
|
@@ -1622,17 +1623,20 @@ void c_typecheck_baset::typecheck_expr_trinary(if_exprt &expr)
|
1622 | 1623 | exprt tmp1=simplify_expr(operands[1], *this);
|
1623 | 1624 | exprt tmp2=simplify_expr(operands[2], *this);
|
1624 | 1625 |
|
1625 |
| - // is one of them void * AND null? Convert that to the other. |
1626 |
| - // (at least that's how GCC behaves) |
| 1626 | + // Is one of them void * AND null? Convert that to the other. |
| 1627 | + // (At least that's how GCC, Clang, and Visual Studio behave. Presence of |
| 1628 | + // symbols blocks them from simplifying the expression to NULL.) |
1627 | 1629 | if(
|
1628 | 1630 | to_pointer_type(operands[1].type()).base_type().id() == ID_empty &&
|
1629 |
| - tmp1.is_constant() && is_null_pointer(to_constant_expr(tmp1))) |
| 1631 | + tmp1.is_constant() && is_null_pointer(to_constant_expr(tmp1)) && |
| 1632 | + find_symbols(operands[1]).empty()) |
1630 | 1633 | {
|
1631 | 1634 | implicit_typecast(operands[1], operands[2].type());
|
1632 | 1635 | }
|
1633 | 1636 | else if(
|
1634 | 1637 | to_pointer_type(operands[2].type()).base_type().id() == ID_empty &&
|
1635 |
| - tmp2.is_constant() && is_null_pointer(to_constant_expr(tmp2))) |
| 1638 | + tmp2.is_constant() && is_null_pointer(to_constant_expr(tmp2)) && |
| 1639 | + find_symbols(operands[2]).empty()) |
1636 | 1640 | {
|
1637 | 1641 | implicit_typecast(operands[2], operands[1].type());
|
1638 | 1642 | }
|
|
0 commit comments