From 762971424f97e32f964f10af03a5f7a3f1d39544 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Mon, 20 Apr 2020 16:31:12 -0400 Subject: [PATCH 061/179] FIXME: get first __analyzer_eval to work --- gcc/analyzer/region-model2.cc | 69 +++++++++++++++++++++-------------- gcc/analyzer/region-model2.h | 6 +-- 2 files changed, 44 insertions(+), 31 deletions(-) diff --git a/gcc/analyzer/region-model2.cc b/gcc/analyzer/region-model2.cc index cf1d2167245..8c7ca1d5b42 100644 --- a/gcc/analyzer/region-model2.cc +++ b/gcc/analyzer/region-model2.cc @@ -418,52 +418,54 @@ region_svalue2::merge_values (const region_svalue2 ®ion2_sval_a, /* Evaluate the condition LHS OP RHS. Subroutine of region_model2::eval_condition for when we have a pair of pointers. */ -#if 0 + tristate region_svalue2::eval_condition (region_svalue2 *lhs, enum tree_code op, region_svalue2 *rhs) { /* See if they point to the same region2. */ + region2 *lhs_reg = lhs->get_pointee (); + region2 *rhs_reg = rhs->get_pointee (); + bool ptr_equality = lhs_reg == rhs_reg; /* TODO: what about child region2s where the child is the first child - (or descendent)? */ - region2_id lhs_reg = lhs->get_pointee (); - region2_id rhs_reg = rhs->get_pointee (); + (or descendent)? + Presumably we should look at base regions and compare offsets + within them. */ switch (op) { default: gcc_unreachable (); case EQ_EXPR: - if (lhs_reg == rhs_reg) + if (ptr_equality) return tristate::TS_TRUE; else return tristate::TS_FALSE; break; case NE_EXPR: - if (lhs_reg != rhs_reg) - return tristate::TS_TRUE; - else + if (ptr_equality) return tristate::TS_FALSE; + else + return tristate::TS_TRUE; break; case GE_EXPR: case LE_EXPR: - if (lhs_reg == rhs_reg) + if (ptr_equality) return tristate::TS_TRUE; break; case GT_EXPR: case LT_EXPR: - if (lhs_reg == rhs_reg) + if (ptr_equality) return tristate::TS_FALSE; break; } return tristate::TS_UNKNOWN; } -#endif /* class constant_svalue2 : public svalue2. */ @@ -536,7 +538,7 @@ constant_svalue2::merge_values (const constant_svalue2 &cst_sval_a, /* Evaluate the condition LHS OP RHS. Subroutine of region_model2::eval_condition for when we have a pair of constants. */ -#if 0 + tristate constant_svalue2::eval_condition (constant_svalue2 *lhs, enum tree_code op, @@ -560,7 +562,6 @@ constant_svalue2::eval_condition (constant_svalue2 *lhs, } return tristate::TS_UNKNOWN; } -#endif /* Implementation of svalue2::print_details vfunc for constant_svalue2. */ #if 0 @@ -3805,6 +3806,22 @@ region_model2::on_gcall (const supernode *snode, { // TODO //gcc_unreachable (); + + if (is_special_named_call_p (call, "__analyzer_eval", 1)) + { + /* Handle the builtin "__analyzer_eval" by evaluating the input + and dumping as a dummy warning, so that test cases can use + dg-warning to validate the result (and so unexpected warnings will + lead to DejaGnu failures). */ + tree t_arg = gimple_call_arg (call, 0); + tristate t + = eval_condition (t_arg, + NE_EXPR, + integer_zero_node, + NULL/*&ctxt*/); // FIXME + warning_at (call->location, 0, "%s", t.as_string ()); + } + return true; } @@ -5005,7 +5022,7 @@ region_model2::clobber_region (region2 *reg) tristate region_model2::eval_condition (svalue2 *lhs, - enum tree_code /*op*/, + enum tree_code op, svalue2 *rhs) const { /* For now, make no attempt to capture constraints on floating-point @@ -5014,17 +5031,16 @@ region_model2::eval_condition (svalue2 *lhs, || (rhs->get_type () && FLOAT_TYPE_P (rhs->get_type ()))) return tristate::unknown (); - return tristate::unknown (); // TODO - -#if 0 - tristate ts = eval_condition_without_cm (lhs_sval, op, rhs_sval); - + tristate ts = eval_condition_without_cm (lhs, op, rhs); if (ts.is_known ()) return ts; +#if 0 /* Otherwise, try constraints. */ return m_constraints->eval_condition (lhs_sval, op, rhs_sval); #endif + return tristate::unknown (); // TODO + } /* Determine what is known about the condition "LHS_SVAL OP RHS_SVAL" within @@ -5033,14 +5049,12 @@ region_model2::eval_condition (svalue2 *lhs, This is exposed so that impl_region_model2_context::on_state_leak can check for equality part-way through region_model2::purge_unused_svalue2s without risking creating new ECs. */ -#if 0 + tristate -region_model2::eval_condition_without_cm (svalue2 *lhs_sval, - enum tree_code op, - svalue2 *rhs_sval) const +region_model2::eval_condition_without_cm (svalue2 *lhs, + enum tree_code op, + svalue2 *rhs) const { - svalue2 *lhs = get_svalue2 (lhs_sval); - svalue2 *rhs = get_svalue2 (rhs_sval); gcc_assert (lhs); gcc_assert (rhs); @@ -5092,13 +5106,14 @@ region_model2::eval_condition_without_cm (svalue2 *lhs_sval, return constant_svalue2::eval_condition (cst_lhs, op, cst_rhs); /* Handle comparison of a region_svalue2 against zero. */ +#if 0 if (region_svalue2 *ptr = lhs->dyn_cast_region_svalue2 ()) if (constant_svalue2 *cst_rhs = rhs->dyn_cast_constant_svalue2 ()) if (zerop (cst_rhs->get_constant ())) { /* A region_svalue2 is a non-NULL pointer, except in certain special cases (see the comment for region2::non_null_p. */ - region2 *pointee = get_region2 (ptr->get_pointee ()); + region2 *pointee = ptr->get_pointee (); if (pointee->non_null_p (*this)) { switch (op) @@ -5118,11 +5133,11 @@ region_model2::eval_condition_without_cm (svalue2 *lhs_sval, } } } +#endif } return tristate::TS_UNKNOWN; } -#endif /* Attempt to add the constraint "LHS OP RHS" to this region_model2. If it is consistent with existing constraints, add it, and return true. diff --git a/gcc/analyzer/region-model2.h b/gcc/analyzer/region-model2.h index d00f207eb41..cc536ce72da 100644 --- a/gcc/analyzer/region-model2.h +++ b/gcc/analyzer/region-model2.h @@ -1680,11 +1680,9 @@ class region_model2 tristate eval_condition (svalue2 *lhs, enum tree_code op, svalue2 *rhs) const; -#if 0 - tristate eval_condition_without_cm (svalue2_id lhs, + tristate eval_condition_without_cm (svalue2 *lhs, enum tree_code op, - svalue2_id rhs) const; -#endif + svalue2 *rhs) const; tristate eval_condition (tree lhs, enum tree_code op, tree rhs, -- 2.21.0