One final tweak to the range-ops API.

Most fold_range calls were returning true, which was a trigger for the original change to return by value.   When I changed it back to a return by reference, I should also have added the boolean result back.  Now all 3 routines are similar...

    virtual bool fold_range (value_range &r, tree type, const value_range &lh, const value_range &rh) const;     virtual bool op1_range (value_range &r, tree type, const value_range &lhs, const value_range &op2) const;     virtual bool op2_range (value_range &r, tree type, const value_range &lhs, const value_range &op1) const;

And again, this is pretty mechanical.  bootstraps and passes all tests.

Checked in as revision 278266

Andrew
2019-11-14  Andrew MacLeod  <amacl...@redhat.com>

	* range-op.h (range_operator::fold_range): Return a bool.
	* range-op.cc (range_operator::wi_fold): Assert supported type.
	(range_operator::fold_range): Assert supported type and return true.
	(operator_equal::fold_range): Return true.
	(operator_not_equal::fold_range): Same.
	(operator_lt::fold_range): Same.
	(operator_le::fold_range): Same.
	(operator_gt::fold_range): Same.
	(operator_ge::fold_range): Same.
	(operator_plus::op1_range): Adjust call to fold_range.
	(operator_plus::op2_range): Same.
	(operator_minus::op1_range): Same.
	(operator_minus::op2_range): Same.
	(operator_exact_divide::op1_range): Same.
	(operator_lshift::fold_range): Return true and adjust fold_range call.
	(operator_rshift::fold_range): Same.
	(operator_cast::fold_range): Return true.
	(operator_logical_and::fold_range): Same.
	(operator_logical_or::fold_range): Same.
	(operator_logical_not::fold_range): Same.
	(operator_bitwise_not::fold_range): Adjust call to fold_range.
	(operator_bitwise_not::op1_range): Same.
	(operator_cst::fold_range): Return true.
	(operator_identity::fold_range): Return true.
	(operator_negate::fold_range): Return true and adjust fold_range call.
	(operator_addr_expr::fold_range): Return true.
	(operator_addr_expr::op1_range): Adjust call to fold_range.
	(range_cast): Same.
	* tree-vrp.c (range_fold_binary_symbolics_p): Adjust call to fold_range.
	(range_fold_unary_symbolics_p): Same.

Index: range-op.h
===================================================================
*** range-op.h	(revision 278265)
--- range-op.h	(working copy)
*************** class range_operator
*** 50,56 ****
  {
  public:
    // Perform an operation between 2 ranges and return it.
!   virtual void fold_range (value_range &r, tree type,
  			   const value_range &lh,
  			   const value_range &rh) const;
  
--- 50,56 ----
  {
  public:
    // Perform an operation between 2 ranges and return it.
!   virtual bool fold_range (value_range &r, tree type,
  			   const value_range &lh,
  			   const value_range &rh) const;
  
*************** public:
*** 73,79 ****
  			  const value_range &op1) const;
  
  protected:
!   // Perform an operation between 2 sub-ranges and return it.
    virtual void wi_fold (value_range &r, tree type,
  		        const wide_int &lh_lb,
  		        const wide_int &lh_ub,
--- 73,79 ----
  			  const value_range &op1) const;
  
  protected:
!   // Perform an integral operation between 2 sub-ranges and return it.
    virtual void wi_fold (value_range &r, tree type,
  		        const wide_int &lh_lb,
  		        const wide_int &lh_ub,
Index: range-op.cc
===================================================================
*** range-op.cc	(revision 278265)
--- range-op.cc	(working copy)
*************** range_operator::wi_fold (value_range &r,
*** 131,149 ****
  			 const wide_int &rh_lb ATTRIBUTE_UNUSED,
  			 const wide_int &rh_ub ATTRIBUTE_UNUSED) const
  {
    r = value_range (type);
  }
  
  // The default for fold is to break all ranges into sub-ranges and
  // invoke the wi_fold method on each sub-range pair.
  
! void
  range_operator::fold_range (value_range &r, tree type,
  			    const value_range &lh,
  			    const value_range &rh) const
  {
    if (empty_range_check (r, lh, rh))
!     return;
  
    value_range tmp;
    r.set_undefined ();
--- 131,151 ----
  			 const wide_int &rh_lb ATTRIBUTE_UNUSED,
  			 const wide_int &rh_ub ATTRIBUTE_UNUSED) const
  {
+   gcc_checking_assert (value_range::supports_type_p (type));
    r = value_range (type);
  }
  
  // The default for fold is to break all ranges into sub-ranges and
  // invoke the wi_fold method on each sub-range pair.
  
! bool
  range_operator::fold_range (value_range &r, tree type,
  			    const value_range &lh,
  			    const value_range &rh) const
  {
+   gcc_checking_assert (value_range::supports_type_p (type));
    if (empty_range_check (r, lh, rh))
!     return true;
  
    value_range tmp;
    r.set_undefined ();
*************** range_operator::fold_range (value_range
*** 157,164 ****
  	wi_fold (tmp, type, lh_lb, lh_ub, rh_lb, rh_ub);
  	r.union_ (tmp);
  	if (r.varying_p ())
! 	  return;
        }
  }
  
  // The default for op1_range is to return false.
--- 159,167 ----
  	wi_fold (tmp, type, lh_lb, lh_ub, rh_lb, rh_ub);
  	r.union_ (tmp);
  	if (r.varying_p ())
! 	  return true;
        }
+   return true;
  }
  
  // The default for op1_range is to return false.
*************** get_bool_state (value_range &r, const va
*** 364,370 ****
  class operator_equal : public range_operator
  {
  public:
!   virtual void fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
    virtual bool op1_range (value_range &r, tree type,
--- 367,373 ----
  class operator_equal : public range_operator
  {
  public:
!   virtual bool fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
    virtual bool op1_range (value_range &r, tree type,
*************** public:
*** 375,387 ****
  			  const value_range &val) const;
  } op_equal;
  
! void
  operator_equal::fold_range (value_range &r, tree type,
  			    const value_range &op1,
  			    const value_range &op2) const
  {
    if (empty_range_check (r, op1, op2))
!     return;
  
    // We can be sure the values are always equal or not if both ranges
    // consist of a single value, and then compare them.
--- 378,390 ----
  			  const value_range &val) const;
  } op_equal;
  
! bool
  operator_equal::fold_range (value_range &r, tree type,
  			    const value_range &op1,
  			    const value_range &op2) const
  {
    if (empty_range_check (r, op1, op2))
!     return true;
  
    // We can be sure the values are always equal or not if both ranges
    // consist of a single value, and then compare them.
*************** operator_equal::fold_range (value_range
*** 404,409 ****
--- 407,413 ----
        else
  	r = range_true_and_false (type);
      }
+   return true;
  }
  
  bool
*************** operator_equal::op2_range (value_range &
*** 448,454 ****
  class operator_not_equal : public range_operator
  {
  public:
!   virtual void fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
    virtual bool op1_range (value_range &r, tree type,
--- 452,458 ----
  class operator_not_equal : public range_operator
  {
  public:
!   virtual bool fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
    virtual bool op1_range (value_range &r, tree type,
*************** public:
*** 459,471 ****
  			  const value_range &op1) const;
  } op_not_equal;
  
! void
  operator_not_equal::fold_range (value_range &r, tree type,
  				const value_range &op1,
  				const value_range &op2) const
  {
    if (empty_range_check (r, op1, op2))
!     return;
  
    // We can be sure the values are always equal or not if both ranges
    // consist of a single value, and then compare them.
--- 463,475 ----
  			  const value_range &op1) const;
  } op_not_equal;
  
! bool
  operator_not_equal::fold_range (value_range &r, tree type,
  				const value_range &op1,
  				const value_range &op2) const
  {
    if (empty_range_check (r, op1, op2))
!     return true;
  
    // We can be sure the values are always equal or not if both ranges
    // consist of a single value, and then compare them.
*************** operator_not_equal::fold_range (value_ra
*** 488,493 ****
--- 492,498 ----
        else
  	r = range_true_and_false (type);
      }
+   return true;
  }
  
  bool
*************** build_ge (value_range &r, tree type, con
*** 578,584 ****
  class operator_lt :  public range_operator
  {
  public:
!   virtual void fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
    virtual bool op1_range (value_range &r, tree type,
--- 583,589 ----
  class operator_lt :  public range_operator
  {
  public:
!   virtual bool fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
    virtual bool op1_range (value_range &r, tree type,
*************** public:
*** 589,601 ****
  			  const value_range &op1) const;
  } op_lt;
  
! void
  operator_lt::fold_range (value_range &r, tree type,
  			 const value_range &op1,
  			 const value_range &op2) const
  {
    if (empty_range_check (r, op1, op2))
!     return;
  
    signop sign = TYPE_SIGN (op1.type ());
    gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
--- 594,606 ----
  			  const value_range &op1) const;
  } op_lt;
  
! bool
  operator_lt::fold_range (value_range &r, tree type,
  			 const value_range &op1,
  			 const value_range &op2) const
  {
    if (empty_range_check (r, op1, op2))
!     return true;
  
    signop sign = TYPE_SIGN (op1.type ());
    gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
*************** operator_lt::fold_range (value_range &r,
*** 606,611 ****
--- 611,617 ----
      r = range_false (type);
    else
      r = range_true_and_false (type);
+   return true;
  }
  
  bool
*************** operator_lt::op2_range (value_range &r,
*** 654,660 ****
  class operator_le :  public range_operator
  {
  public:
!   virtual void fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
    virtual bool op1_range (value_range &r, tree type,
--- 660,666 ----
  class operator_le :  public range_operator
  {
  public:
!   virtual bool fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
    virtual bool op1_range (value_range &r, tree type,
*************** public:
*** 665,677 ****
  			  const value_range &op1) const;
  } op_le;
  
! void
  operator_le::fold_range (value_range &r, tree type,
  			 const value_range &op1,
  			 const value_range &op2) const
  {
    if (empty_range_check (r, op1, op2))
!     return;
  
    signop sign = TYPE_SIGN (op1.type ());
    gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
--- 671,683 ----
  			  const value_range &op1) const;
  } op_le;
  
! bool
  operator_le::fold_range (value_range &r, tree type,
  			 const value_range &op1,
  			 const value_range &op2) const
  {
    if (empty_range_check (r, op1, op2))
!     return true;
  
    signop sign = TYPE_SIGN (op1.type ());
    gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
*************** operator_le::fold_range (value_range &r,
*** 682,687 ****
--- 688,694 ----
      r = range_false (type);
    else
      r = range_true_and_false (type);
+   return true;
  }
  
  bool
*************** operator_le::op2_range (value_range &r,
*** 730,736 ****
  class operator_gt :  public range_operator
  {
  public:
!   virtual void fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
    virtual bool op1_range (value_range &r, tree type,
--- 737,743 ----
  class operator_gt :  public range_operator
  {
  public:
!   virtual bool fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
    virtual bool op1_range (value_range &r, tree type,
*************** public:
*** 741,752 ****
  			  const value_range &op1) const;
  } op_gt;
  
! void
  operator_gt::fold_range (value_range &r, tree type,
  			 const value_range &op1, const value_range &op2) const
  {
    if (empty_range_check (r, op1, op2))
!     return;
  
    signop sign = TYPE_SIGN (op1.type ());
    gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
--- 748,759 ----
  			  const value_range &op1) const;
  } op_gt;
  
! bool
  operator_gt::fold_range (value_range &r, tree type,
  			 const value_range &op1, const value_range &op2) const
  {
    if (empty_range_check (r, op1, op2))
!     return true;
  
    signop sign = TYPE_SIGN (op1.type ());
    gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
*************** operator_gt::fold_range (value_range &r,
*** 757,762 ****
--- 764,770 ----
      r = range_false (type);
    else
      r = range_true_and_false (type);
+   return true;
  }
  
  bool
*************** operator_gt::op2_range (value_range &r,
*** 804,810 ****
  class operator_ge :  public range_operator
  {
  public:
!   virtual void fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
    virtual bool op1_range (value_range &r, tree type,
--- 812,818 ----
  class operator_ge :  public range_operator
  {
  public:
!   virtual bool fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
    virtual bool op1_range (value_range &r, tree type,
*************** public:
*** 815,827 ****
  			  const value_range &op1) const;
  } op_ge;
  
! void
  operator_ge::fold_range (value_range &r, tree type,
  			 const value_range &op1,
  			 const value_range &op2) const
  {
    if (empty_range_check (r, op1, op2))
!     return;
  
    signop sign = TYPE_SIGN (op1.type ());
    gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
--- 823,835 ----
  			  const value_range &op1) const;
  } op_ge;
  
! bool
  operator_ge::fold_range (value_range &r, tree type,
  			 const value_range &op1,
  			 const value_range &op2) const
  {
    if (empty_range_check (r, op1, op2))
!     return true;
  
    signop sign = TYPE_SIGN (op1.type ());
    gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
*************** operator_ge::fold_range (value_range &r,
*** 832,837 ****
--- 840,846 ----
      r = range_false (type);
    else
      r = range_true_and_false (type);
+   return true;
  }
  
  bool
*************** operator_plus::op1_range (value_range &r
*** 910,917 ****
  			  const value_range &lhs,
  			  const value_range &op2) const
  {
!   range_op_handler (MINUS_EXPR, type)->fold_range (r, type, lhs, op2);
!   return true;
  }
  
  bool
--- 919,925 ----
  			  const value_range &lhs,
  			  const value_range &op2) const
  {
!   return range_op_handler (MINUS_EXPR, type)->fold_range (r, type, lhs, op2);
  }
  
  bool
*************** operator_plus::op2_range (value_range &r
*** 919,926 ****
  			  const value_range &lhs,
  			  const value_range &op1) const
  {
!   range_op_handler (MINUS_EXPR, type)->fold_range (r, type, lhs, op1);
!   return true;
  }
  
  
--- 927,933 ----
  			  const value_range &lhs,
  			  const value_range &op1) const
  {
!   return range_op_handler (MINUS_EXPR, type)->fold_range (r, type, lhs, op1);
  }
  
  
*************** operator_minus::op1_range (value_range &
*** 957,964 ****
  			   const value_range &lhs,
  			   const value_range &op2) const
  {
!   range_op_handler (PLUS_EXPR, type)->fold_range (r, type, lhs, op2);
!   return true;
  }
  
  bool
--- 964,970 ----
  			   const value_range &lhs,
  			   const value_range &op2) const
  {
!   return range_op_handler (PLUS_EXPR, type)->fold_range (r, type, lhs, op2);
  }
  
  bool
*************** operator_minus::op2_range (value_range &
*** 966,973 ****
  			   const value_range &lhs,
  			   const value_range &op1) const
  {
!   fold_range (r, type, op1, lhs);
!   return true;
  }
  
  
--- 972,978 ----
  			   const value_range &lhs,
  			   const value_range &op1) const
  {
!   return fold_range (r, type, op1, lhs);
  }
  
  
*************** operator_exact_divide::op1_range (value_
*** 1351,1360 ****
    // If op2 is a multiple of 2, we would be able to set some non-zero bits.
    if (op2.singleton_p (&offset)
        && !integer_zerop (offset))
!     {
!       range_op_handler (MULT_EXPR, type)->fold_range (r, type, lhs, op2);
!       return true;
!     }
    return false;
  }
  
--- 1356,1362 ----
    // If op2 is a multiple of 2, we would be able to set some non-zero bits.
    if (op2.singleton_p (&offset)
        && !integer_zerop (offset))
!     return range_op_handler (MULT_EXPR, type)->fold_range (r, type, lhs, op2);
    return false;
  }
  
*************** operator_exact_divide::op1_range (value_
*** 1362,1368 ****
  class operator_lshift : public cross_product_operator
  {
  public:
!   virtual void fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
  
--- 1364,1370 ----
  class operator_lshift : public cross_product_operator
  {
  public:
!   virtual bool fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
  
*************** public:
*** 1375,1387 ****
  				const wide_int &) const;
  } op_lshift;
  
! void
  operator_lshift::fold_range (value_range &r, tree type,
  			     const value_range &op1,
  			     const value_range &op2) const
  {
    if (undefined_shift_range_check (r, type, op2))
!     return;
  
    // Transform left shifts by constants into multiplies.
    if (op2.singleton_p ())
--- 1377,1389 ----
  				const wide_int &) const;
  } op_lshift;
  
! bool
  operator_lshift::fold_range (value_range &r, tree type,
  			     const value_range &op1,
  			     const value_range &op2) const
  {
    if (undefined_shift_range_check (r, type, op2))
!     return true;
  
    // Transform left shifts by constants into multiplies.
    if (op2.singleton_p ())
*************** operator_lshift::fold_range (value_range
*** 1395,1408 ****
        bool saved_flag_wrapv_pointer = flag_wrapv_pointer;
        flag_wrapv = 1;
        flag_wrapv_pointer = 1;
!       range_op_handler (MULT_EXPR, type)->fold_range (r, type, op1, mult);
        flag_wrapv = saved_flag_wrapv;
        flag_wrapv_pointer = saved_flag_wrapv_pointer;
!       return;
      }
! 
!   // Otherwise, invoke the generic fold routine.
!   range_operator::fold_range (r, type, op1, op2);
  }
  
  void
--- 1397,1411 ----
        bool saved_flag_wrapv_pointer = flag_wrapv_pointer;
        flag_wrapv = 1;
        flag_wrapv_pointer = 1;
!       bool b = range_op_handler (MULT_EXPR, type)->fold_range (r, type, op1,
! 							       mult);
        flag_wrapv = saved_flag_wrapv;
        flag_wrapv_pointer = saved_flag_wrapv_pointer;
!       return b;
      }
!   else
!     // Otherwise, invoke the generic fold routine.
!     return range_operator::fold_range (r, type, op1, op2);
  }
  
  void
*************** operator_lshift::wi_op_overflows (wide_i
*** 1486,1492 ****
  class operator_rshift : public cross_product_operator
  {
  public:
!   virtual void fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
    virtual void wi_fold (value_range &r, tree type,
--- 1489,1495 ----
  class operator_rshift : public cross_product_operator
  {
  public:
!   virtual bool fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
    virtual void wi_fold (value_range &r, tree type,
*************** operator_rshift::wi_op_overflows (wide_i
*** 1519,1534 ****
    return false;
  }
  
! void
  operator_rshift::fold_range (value_range &r, tree type,
  			     const value_range &op1,
  			     const value_range &op2) const
  {
    if (undefined_shift_range_check (r, type, op2))
!     return;
  
!   // Otherwise, invoke the generic fold routine.
!   range_operator::fold_range (r, type, op1, op2);
  }
  
  void
--- 1522,1537 ----
    return false;
  }
  
! bool
  operator_rshift::fold_range (value_range &r, tree type,
  			     const value_range &op1,
  			     const value_range &op2) const
  {
+   // Invoke the generic fold routine if not undefined..
    if (undefined_shift_range_check (r, type, op2))
!     return true;
  
!   return range_operator::fold_range (r, type, op1, op2);
  }
  
  void
*************** operator_rshift::wi_fold (value_range &r
*** 1543,1549 ****
  class operator_cast: public range_operator
  {
  public:
!   virtual void fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
    virtual bool op1_range (value_range &r, tree type,
--- 1546,1552 ----
  class operator_cast: public range_operator
  {
  public:
!   virtual bool fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
    virtual bool op1_range (value_range &r, tree type,
*************** public:
*** 1552,1564 ****
  
  } op_convert;
  
! void
  operator_cast::fold_range (value_range &r, tree type ATTRIBUTE_UNUSED,
  			   const value_range &lh,
  			   const value_range &rh) const
  {
    if (empty_range_check (r, lh, rh))
!     return;
    
    tree inner = lh.type ();
    tree outer = rh.type ();
--- 1555,1567 ----
  
  } op_convert;
  
! bool
  operator_cast::fold_range (value_range &r, tree type ATTRIBUTE_UNUSED,
  			   const value_range &lh,
  			   const value_range &rh) const
  {
    if (empty_range_check (r, lh, rh))
!     return true;
    
    tree inner = lh.type ();
    tree outer = rh.type ();
*************** operator_cast::fold_range (value_range &
*** 1598,1605 ****
  	    }
  	}
        r = value_range (type);
!       return;
      }
  }
  
  bool
--- 1601,1609 ----
  	    }
  	}
        r = value_range (type);
!       break;
      }
+   return true;
  }
  
  bool
*************** operator_cast::op1_range (value_range &r
*** 1682,1688 ****
  class operator_logical_and : public range_operator
  {
  public:
!   virtual void fold_range (value_range &r, tree type,
  			   const value_range &lh,
  			   const value_range &rh) const;
    virtual bool op1_range (value_range &r, tree type,
--- 1686,1692 ----
  class operator_logical_and : public range_operator
  {
  public:
!   virtual bool fold_range (value_range &r, tree type,
  			   const value_range &lh,
  			   const value_range &rh) const;
    virtual bool op1_range (value_range &r, tree type,
*************** public:
*** 1694,1706 ****
  } op_logical_and;
  
  
! void
  operator_logical_and::fold_range (value_range &r, tree type,
  				  const value_range &lh,
  				  const value_range &rh) const
  {
    if (empty_range_check (r, lh, rh))
!     return;
  
    // 0 && anything is 0.
    if ((wi::eq_p (lh.lower_bound (), 0) && wi::eq_p (lh.upper_bound (), 0))
--- 1698,1710 ----
  } op_logical_and;
  
  
! bool
  operator_logical_and::fold_range (value_range &r, tree type,
  				  const value_range &lh,
  				  const value_range &rh) const
  {
    if (empty_range_check (r, lh, rh))
!     return true;
  
    // 0 && anything is 0.
    if ((wi::eq_p (lh.lower_bound (), 0) && wi::eq_p (lh.upper_bound (), 0))
*************** operator_logical_and::fold_range (value_
*** 1713,1718 ****
--- 1717,1723 ----
      r = range_true_and_false (type);
    else
      r = range_true (type);
+   return true;
  }
  
  bool
*************** operator_bitwise_and::op2_range (value_r
*** 1964,1970 ****
  class operator_logical_or : public range_operator
  {
  public:
!   virtual void fold_range (value_range &r, tree type,
  			   const value_range &lh,
  			   const value_range &rh) const;
    virtual bool op1_range (value_range &r, tree type,
--- 1969,1975 ----
  class operator_logical_or : public range_operator
  {
  public:
!   virtual bool fold_range (value_range &r, tree type,
  			   const value_range &lh,
  			   const value_range &rh) const;
    virtual bool op1_range (value_range &r, tree type,
*************** public:
*** 1975,1990 ****
  			  const value_range &op1) const;
  } op_logical_or;
  
! void
  operator_logical_or::fold_range (value_range &r, tree type ATTRIBUTE_UNUSED,
  				 const value_range &lh,
  				 const value_range &rh) const
  {
    if (empty_range_check (r, lh, rh))
!     return;
  
    r = lh;
    r.union_ (rh);
  }
  
  bool
--- 1980,1996 ----
  			  const value_range &op1) const;
  } op_logical_or;
  
! bool
  operator_logical_or::fold_range (value_range &r, tree type ATTRIBUTE_UNUSED,
  				 const value_range &lh,
  				 const value_range &rh) const
  {
    if (empty_range_check (r, lh, rh))
!     return true;
  
    r = lh;
    r.union_ (rh);
+   return true;
  }
  
  bool
*************** operator_trunc_mod::wi_fold (value_range
*** 2198,2204 ****
  class operator_logical_not : public range_operator
  {
  public:
!   virtual void fold_range (value_range &r, tree type,
  			   const value_range &lh,
  			   const value_range &rh) const;
    virtual bool op1_range (value_range &r, tree type,
--- 2204,2210 ----
  class operator_logical_not : public range_operator
  {
  public:
!   virtual bool fold_range (value_range &r, tree type,
  			   const value_range &lh,
  			   const value_range &rh) const;
    virtual bool op1_range (value_range &r, tree type,
*************** public:
*** 2220,2232 ****
  // 	 b_2 = x_1 < 20		[0,0] = x_1 < 20,   false, so x_1 == [20, 255]
  //   which is the result we are looking for.. so.. pass it through.
  
! void
  operator_logical_not::fold_range (value_range &r, tree type,
  				  const value_range &lh,
  				  const value_range &rh ATTRIBUTE_UNUSED) const
  {
    if (empty_range_check (r, lh, rh))
!     return;
  
    if (lh.varying_p () || lh.undefined_p ())
      r = lh;
--- 2226,2238 ----
  // 	 b_2 = x_1 < 20		[0,0] = x_1 < 20,   false, so x_1 == [20, 255]
  //   which is the result we are looking for.. so.. pass it through.
  
! bool
  operator_logical_not::fold_range (value_range &r, tree type,
  				  const value_range &lh,
  				  const value_range &rh ATTRIBUTE_UNUSED) const
  {
    if (empty_range_check (r, lh, rh))
!     return true;
  
    if (lh.varying_p () || lh.undefined_p ())
      r = lh;
*************** operator_logical_not::fold_range (value_
*** 2236,2242 ****
        r.invert ();
      }
    gcc_checking_assert (lh.type() == type);
!   return;
  }
  
  bool
--- 2242,2248 ----
        r.invert ();
      }
    gcc_checking_assert (lh.type() == type);
!   return true;
  }
  
  bool
*************** operator_logical_not::op1_range (value_r
*** 2255,2261 ****
  class operator_bitwise_not : public range_operator
  {
  public:
!   virtual void fold_range (value_range &r, tree type,
  			   const value_range &lh,
  			   const value_range &rh) const;
    virtual bool op1_range (value_range &r, tree type,
--- 2261,2267 ----
  class operator_bitwise_not : public range_operator
  {
  public:
!   virtual bool fold_range (value_range &r, tree type,
  			   const value_range &lh,
  			   const value_range &rh) const;
    virtual bool op1_range (value_range &r, tree type,
*************** public:
*** 2263,2281 ****
  			  const value_range &op2) const;
  } op_bitwise_not;
  
! void
  operator_bitwise_not::fold_range (value_range &r, tree type,
  				  const value_range &lh,
  				  const value_range &rh) const
  {
    if (empty_range_check (r, lh, rh))
!     return;
  
    // ~X is simply -1 - X.
    value_range minusone (type, wi::minus_one (TYPE_PRECISION (type)),
  			wi::minus_one (TYPE_PRECISION (type)));
!   range_op_handler (MINUS_EXPR, type)->fold_range (r, type, minusone, lh);
!   return;
  }
  
  bool
--- 2269,2287 ----
  			  const value_range &op2) const;
  } op_bitwise_not;
  
! bool
  operator_bitwise_not::fold_range (value_range &r, tree type,
  				  const value_range &lh,
  				  const value_range &rh) const
  {
    if (empty_range_check (r, lh, rh))
!     return true;
  
    // ~X is simply -1 - X.
    value_range minusone (type, wi::minus_one (TYPE_PRECISION (type)),
  			wi::minus_one (TYPE_PRECISION (type)));
!   return range_op_handler (MINUS_EXPR, type)->fold_range (r, type, minusone,
! 							  lh);
  }
  
  bool
*************** operator_bitwise_not::op1_range (value_r
*** 2284,2315 ****
  				 const value_range &op2) const
  {
    // ~X is -1 - X and since bitwise NOT is involutary...do it again.
!   fold_range (r, type, lhs, op2);
!   return true;
  }
  
  
  class operator_cst : public range_operator
  {
  public:
!   virtual void fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
  } op_integer_cst;
  
! void
  operator_cst::fold_range (value_range &r, tree type ATTRIBUTE_UNUSED,
  			  const value_range &lh,
  			  const value_range &rh ATTRIBUTE_UNUSED) const
  {
    r = lh;
  }
  
  
  class operator_identity : public range_operator
  {
  public:
!   virtual void fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
    virtual bool op1_range (value_range &r, tree type,
--- 2290,2321 ----
  				 const value_range &op2) const
  {
    // ~X is -1 - X and since bitwise NOT is involutary...do it again.
!   return fold_range (r, type, lhs, op2);
  }
  
  
  class operator_cst : public range_operator
  {
  public:
!   virtual bool fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
  } op_integer_cst;
  
! bool
  operator_cst::fold_range (value_range &r, tree type ATTRIBUTE_UNUSED,
  			  const value_range &lh,
  			  const value_range &rh ATTRIBUTE_UNUSED) const
  {
    r = lh;
+   return true;
  }
  
  
  class operator_identity : public range_operator
  {
  public:
!   virtual bool fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
    virtual bool op1_range (value_range &r, tree type,
*************** public:
*** 2317,2328 ****
  			  const value_range &op2) const;
  } op_identity;
  
! void
  operator_identity::fold_range (value_range &r, tree type ATTRIBUTE_UNUSED,
  			       const value_range &lh,
  			       const value_range &rh ATTRIBUTE_UNUSED) const
  {
    r = lh;
  }
  
  bool
--- 2323,2335 ----
  			  const value_range &op2) const;
  } op_identity;
  
! bool
  operator_identity::fold_range (value_range &r, tree type ATTRIBUTE_UNUSED,
  			       const value_range &lh,
  			       const value_range &rh ATTRIBUTE_UNUSED) const
  {
    r = lh;
+   return true;
  }
  
  bool
*************** operator_absu::wi_fold (value_range &r,
*** 2485,2491 ****
  class operator_negate : public range_operator
  {
   public:
!   virtual void fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
    virtual bool op1_range (value_range &r, tree type,
--- 2492,2498 ----
  class operator_negate : public range_operator
  {
   public:
!   virtual bool fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
    virtual bool op1_range (value_range &r, tree type,
*************** class operator_negate : public range_ope
*** 2493,2508 ****
  			  const value_range &op2) const;
  } op_negate;
  
! void
  operator_negate::fold_range (value_range &r, tree type,
  			     const value_range &lh,
  			     const value_range &rh) const
  {
    if (empty_range_check (r, lh, rh))
!     return;
    // -X is simply 0 - X.
!   range_op_handler (MINUS_EXPR, type)->fold_range (r, type,
! 						   range_zero (type), lh);
  }
  
  bool
--- 2500,2516 ----
  			  const value_range &op2) const;
  } op_negate;
  
! bool
  operator_negate::fold_range (value_range &r, tree type,
  			     const value_range &lh,
  			     const value_range &rh) const
  {
    if (empty_range_check (r, lh, rh))
!     return true;
    // -X is simply 0 - X.
!   return range_op_handler (MINUS_EXPR, type)->fold_range (r, type,
! 							  range_zero (type),
! 							  lh);
  }
  
  bool
*************** operator_negate::op1_range (value_range
*** 2511,2525 ****
  			    const value_range &op2) const
  {
    // NEGATE is involutory.
!   fold_range (r, type, lhs, op2);
!   return true;
  }
  
  
  class operator_addr_expr : public range_operator
  {
  public:
!   virtual void fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
    virtual bool op1_range (value_range &r, tree type,
--- 2519,2532 ----
  			    const value_range &op2) const
  {
    // NEGATE is involutory.
!   return fold_range (r, type, lhs, op2);
  }
  
  
  class operator_addr_expr : public range_operator
  {
  public:
!   virtual bool fold_range (value_range &r, tree type,
  			   const value_range &op1,
  			   const value_range &op2) const;
    virtual bool op1_range (value_range &r, tree type,
*************** public:
*** 2527,2539 ****
  			  const value_range &op2) const;
  } op_addr;
  
! void
  operator_addr_expr::fold_range (value_range &r, tree type,
  				const value_range &lh,
  				const value_range &rh) const
  {
    if (empty_range_check (r, lh, rh))
!     return;
  
    // Return a non-null pointer of the LHS type (passed in op2).
    if (lh.zero_p ())
--- 2534,2546 ----
  			  const value_range &op2) const;
  } op_addr;
  
! bool
  operator_addr_expr::fold_range (value_range &r, tree type,
  				const value_range &lh,
  				const value_range &rh) const
  {
    if (empty_range_check (r, lh, rh))
!     return true;
  
    // Return a non-null pointer of the LHS type (passed in op2).
    if (lh.zero_p ())
*************** operator_addr_expr::fold_range (value_ra
*** 2542,2547 ****
--- 2549,2555 ----
      r = range_nonzero (type);
    else
      r = value_range (type);
+   return true;
  }
  
  bool
*************** operator_addr_expr::op1_range (value_ran
*** 2549,2556 ****
  			       const value_range &lhs,
  			       const value_range &op2) const
  {
!   operator_addr_expr::fold_range (r, type, lhs, op2);
!   return true;
  }
  
  
--- 2557,2563 ----
  			       const value_range &lhs,
  			       const value_range &op2) const
  {
!   return operator_addr_expr::fold_range (r, type, lhs, op2);
  }
  
  
*************** range_cast (value_range &r, tree type)
*** 2808,2814 ****
  {
    value_range tmp = r;
    range_operator *op = range_op_handler (CONVERT_EXPR, type);
!   op->fold_range (r, type, tmp, value_range (type));
  }
  
  #if CHECKING_P
--- 2815,2823 ----
  {
    value_range tmp = r;
    range_operator *op = range_op_handler (CONVERT_EXPR, type);
!   // Call op_convert, if it fails, the result is varying.
!   if (!op->fold_range (r, type, tmp, value_range (type)))
!     r = value_range (type);
  }
  
  #if CHECKING_P
Index: tree-vrp.c
===================================================================
*** tree-vrp.c	(revision 278265)
--- tree-vrp.c	(working copy)
*************** range_fold_binary_symbolics_p (value_ran
*** 1185,1192 ****
        value_range vr0_cst (*vr0), vr1_cst (*vr1);
        vr0_cst.normalize_symbolics ();
        vr1_cst.normalize_symbolics ();
!       op->fold_range (*vr, expr_type, vr0_cst, vr1_cst);
!       return true;
      }
    return false;
  }
--- 1185,1191 ----
        value_range vr0_cst (*vr0), vr1_cst (*vr1);
        vr0_cst.normalize_symbolics ();
        vr1_cst.normalize_symbolics ();
!       return op->fold_range (*vr, expr_type, vr0_cst, vr1_cst);
      }
    return false;
  }
*************** range_fold_unary_symbolics_p (value_rang
*** 1221,1228 ****
        const range_operator *op = get_range_op_handler (vr, code, expr_type);
        value_range vr0_cst (*vr0);
        vr0_cst.normalize_symbolics ();
!       op->fold_range (*vr, expr_type, vr0_cst, value_range (expr_type));
!       return true;
      }
    return false;
  }
--- 1220,1226 ----
        const range_operator *op = get_range_op_handler (vr, code, expr_type);
        value_range vr0_cst (*vr0);
        vr0_cst.normalize_symbolics ();
!       return op->fold_range (*vr, expr_type, vr0_cst, value_range (expr_type));
      }
    return false;
  }

Reply via email to