From 762971424f97e32f964f10af03a5f7a3f1d39544 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
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 &region2_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

