This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: On-Demand range technology [2/5] - Major Components : How it works

On Tue, 4 Jun 2019, Martin Sebor wrote:

On 5/31/19 9:40 AM, Andrew MacLeod wrote:
On 5/29/19 7:15 AM, Richard Biener wrote:
On Tue, May 28, 2019 at 4:17 PM Andrew MacLeod <> wrote:
On 5/27/19 9:02 AM, Richard Biener wrote:
On Fri, May 24, 2019 at 5:50 PM Andrew MacLeod <> wrote:
The above suggests that iff this is done at all it is not in GORI because
those are not conditional stmts or ranges from feeding those.  The
machinery doing the use-def walking from stmt context also cannot
come along these so I have the suspicion that Ranger cannot handle
telling us that for the stmt following above, for example

    if (_5 != 0)

that _5 is not zero?

Can you clarify?
So there are 2 aspects to this.    the range-ops code for DIV_EXPR, if
asked for the range of op2 () would return ~[0,0] for _5.
But you are also correct in that the walk backwards would not find this.

This is similar functionality to how null_derefs are currently handled,
and in fact could probably be done simultaneously using the same code
base.   I didn't bring null derefs up, but this is a good time :-)

There is a separate class used by the gori-cache which tracks the
non-nullness property at the block level.    It has a single API:
non_null_deref_p (name, bb)    which determines whether the is a
dereference in any BB for NAME, which indicates whether the range has an
implicit ~[0,0] range in that basic block or not.
So when we then have

   _1 = *_2; // after this _2 is non-NULL
   _3 = _1 + 1; // _3 is non-NULL
   _4 = *_3;

when a on-demand user asks whether _3 is non-NULL at the
point of _4 = *_3 we don't have this information?  Since the
per-BB caching will only say _1 is non-NULL after the BB.
I'm also not sure whether _3 ever gets non-NULL during
non-NULL processing of the block since walking immediate uses
doesn't really help here?
presumably _3 is globally non-null due to the definition being (pointer
+ x)  ... ie, _3 has a global range o f ~[0,0] ?
No, _3 is ~[0, 0] because it is derived from _1 which is ~[0, 0] and
you cannot arrive at NULL by pointer arithmetic from a non-NULL pointer.

I'm confused.

_1 was loaded from _2 (thus asserting _2 is non-NULL).  but we have no idea what the range of _1 is, so  how do you assert _1 is [~0,0] ? The only way I see to determine _3 is non-NULL  is through the _4 = *_3 statement.

In the first two statements from the above (where _1 is a pointer):

 _1 = *_2;
 _3 = _1 + 1;

_1 must be non-null because C/C++ define pointer addition only for
non-null pointers, and therefore so must _3.

(int*)0+0 is well-defined, so this uses the fact that 1 is non-null. This is all well done in extract_range_from_binary_expr already, although it seems to miss the (dangerous) optimization NULL + unknown == NULL.

Just in case, a quote:

"When an expression J that has integral type is added to or subtracted
from an expression P of pointer type, the result has the type of P.
(4.1) — If P evaluates to a null pointer value and J evaluates to 0, the
result is a null pointer value.
(4.2) — Otherwise, if P points to element x[i] of an array object x with
n elements, 80 the expressions P + J and J + P (where J has the value j)
point to the (possibly-hypothetical) element x[i + j] if 0 ≤ i + j ≤ n
and the expression P - J points to the (possibly-hypothetical) element
x[i − j] if 0 ≤ i − j ≤ n.
(4.3) — Otherwise, the behavior is undefined"

Or does the middle-end allow arithmetic on null pointers?

When people use -fno-delete-null-pointer-checks because their (embedded) platform has important stuff at address 0, they also want to be able to do arithmetic there.

Marc Glisse

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]