From 13a4e204939e3b6bc1fcec1347a1ed5da54dbe62 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Wed, 8 Jul 2020 17:56:13 -0400 Subject: [PATCH 293/315] FIXME: fix comparison against (T*)NULL when we know result against (S*)NULL --- gcc/analyzer/constraint-manager2.cc | 50 +++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/gcc/analyzer/constraint-manager2.cc b/gcc/analyzer/constraint-manager2.cc index 5c24ca007d0..e1b33aa8f07 100644 --- a/gcc/analyzer/constraint-manager2.cc +++ b/gcc/analyzer/constraint-manager2.cc @@ -1333,6 +1333,56 @@ constraint_manager2::eval_condition (equiv_class2_id lhs_ec, if (tree lhs_const = lhs_ec.get_obj (*this).get_any_constant ()) return compare_constants (lhs_const, op, rhs_const); + /* Check for known inequalities of the form + (LHS_EC != OTHER_CST) or (OTHER_CST != LHS_EC). + If RHS_CONST == OTHER_CST, then we also know that LHS_EC != OTHER_CST. + For example, we might have the constraint + ptr != (void *)0 + so we want the condition + ptr == (foo *)0 + to be false. */ + int i; + constraint2 *c; + FOR_EACH_VEC_ELT (m_constraints, i, c) + { + if (c->m_op == CONSTRAINT2_NE) + { + if (c->m_lhs == lhs_ec) + { + if (tree other_cst = c->m_rhs.get_obj (*this).get_any_constant ()) + if (compare_constants + (rhs_const, EQ_EXPR, other_cst).is_true ()) + { + switch (op) + { + case EQ_EXPR: + return tristate (tristate::TS_FALSE); + case NE_EXPR: + return tristate (tristate::TS_TRUE); + default: + break; + } + } + } + if (c->m_rhs == lhs_ec) + { + if (tree other_cst = c->m_lhs.get_obj (*this).get_any_constant ()) + if (compare_constants + (rhs_const, EQ_EXPR, other_cst).is_true ()) + { + switch (op) + { + case EQ_EXPR: + return tristate (tristate::TS_FALSE); + case NE_EXPR: + return tristate (tristate::TS_TRUE); + default: + break; + } + } + } + } + } /* Look at existing bounds on LHS_EC. */ range2 lhs_bounds = get_ec_bounds (lhs_ec); return lhs_bounds.eval_condition (op, rhs_const); -- 2.26.2