when looking at 117222, I discovered the prange operators need a bit of
auditing.
pointer_plus should be functioning properly, but there were some
pre-Prange remnants hanging around.. there were wide_int and irange
based routines which can no longer be called, so they are dead code and
this removed them.
Bootstraps on x86_64-pc-linux-gnu with no regressions. pushed.
Andrew
From 4eb25bfee859a9161c0fd48215feaf1c307f2480 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacleod@redhat.com>
Date: Mon, 21 Oct 2024 16:47:32 -0400
Subject: [PATCH 1/4] Cleanup pointer_plus_operator.
The POINTER_PLUS operator still carries some remnamts of the old
irange interface, which is now dead code with prange.
* range-op-ptr.cc (pointer_plus_operator::wi_fold): Remove.
(pointer_plus_operator::op2_range): Remove irange variant.
(pointer_plus_operator::update_bitmask): Likewise.
---
gcc/range-op-ptr.cc | 74 +--------------------------------------------
1 file changed, 1 insertion(+), 73 deletions(-)
@@ -302,16 +302,7 @@ public:
const prange &lhs,
const prange &op1,
relation_trio = TRIO_VARYING) const final override;
- virtual void wi_fold (irange &r, tree type,
- const wide_int &lh_lb,
- const wide_int &lh_ub,
- const wide_int &rh_lb,
- const wide_int &rh_ub) const;
- virtual bool op2_range (irange &r, tree type,
- const irange &lhs,
- const irange &op1,
- relation_trio = TRIO_VARYING) const;
- void update_bitmask (irange &r, const irange &lh, const irange &rh) const
+ void update_bitmask (prange &r, const prange &lh, const irange &rh) const
{ update_known_bitmask (r, POINTER_PLUS_EXPR, lh, rh); }
} op_pointer_plus;
@@ -388,69 +379,6 @@ pointer_plus_operator::op2_range (irange &r, tree type,
return true;
}
-void
-pointer_plus_operator::wi_fold (irange &r, tree type,
- const wide_int &lh_lb,
- const wide_int &lh_ub,
- const wide_int &rh_lb,
- const wide_int &rh_ub) const
-{
- // Check for [0,0] + const, and simply return the const.
- if (lh_lb == 0 && lh_ub == 0 && rh_lb == rh_ub)
- {
- r.set (type, rh_lb, rh_lb);
- return;
- }
-
- // For pointer types, we are really only interested in asserting
- // whether the expression evaluates to non-NULL.
- //
- // With -fno-delete-null-pointer-checks we need to be more
- // conservative. As some object might reside at address 0,
- // then some offset could be added to it and the same offset
- // subtracted again and the result would be NULL.
- // E.g.
- // static int a[12]; where &a[0] is NULL and
- // ptr = &a[6];
- // ptr -= 6;
- // ptr will be NULL here, even when there is POINTER_PLUS_EXPR
- // where the first range doesn't include zero and the second one
- // doesn't either. As the second operand is sizetype (unsigned),
- // consider all ranges where the MSB could be set as possible
- // subtractions where the result might be NULL.
- if ((!wi_includes_zero_p (type, lh_lb, lh_ub)
- || !wi_includes_zero_p (type, rh_lb, rh_ub))
- && !TYPE_OVERFLOW_WRAPS (type)
- && (flag_delete_null_pointer_checks
- || !wi::sign_mask (rh_ub)))
- r.set_nonzero (type);
- else if (lh_lb == lh_ub && lh_lb == 0
- && rh_lb == rh_ub && rh_lb == 0)
- r.set_zero (type);
- else
- r.set_varying (type);
-}
-
-bool
-pointer_plus_operator::op2_range (irange &r, tree type,
- const irange &lhs ATTRIBUTE_UNUSED,
- const irange &op1 ATTRIBUTE_UNUSED,
- relation_trio trio) const
-{
- relation_kind rel = trio.lhs_op1 ();
- r.set_varying (type);
-
- // If the LHS and OP1 are equal, the op2 must be zero.
- if (rel == VREL_EQ)
- r.set_zero (type);
- // If the LHS and OP1 are not equal, the offset must be non-zero.
- else if (rel == VREL_NE)
- r.set_nonzero (type);
- else
- return false;
- return true;
-}
-
class pointer_min_max_operator : public range_operator
{
public:
--
2.45.0