On Wed, Apr 17, 2019 at 4:12 PM Uecker, Martin
<[email protected]> wrote:
>
> Am Mittwoch, den 17.04.2019, 15:34 +0200 schrieb Richard Biener:
> > On Wed, Apr 17, 2019 at 2:56 PM Uecker, Martin
> > <[email protected]> wrote:
> > >
> > > Am Mittwoch, den 17.04.2019, 14:41 +0200 schrieb Richard Biener:
> > > > On Wed, Apr 17, 2019 at 1:53 PM Uecker, Martin
> > > > <[email protected]> wrote:
> > > > >
> > > > > > Since
> > > > > > your proposal is based on an abstract machine there isn't anything
> > > > > > like a pointer with multiple provenances (which "anything" is), just
> > > > > > pointers with no provenance (pointing outside of any object), right?
> > > > >
> > > > > This is correct. What the proposal does though is put a limit
> > > > > on where pointers obtained from integers are allowed to point
> > > > > to: They cannot point to non-exposed objects. I assume GCC
> > > > > "anything" provenances also cannot point to all possible
> > > > > objects.
> > > >
> > > > Yes. We exclude objects that do not have their address taken
> > > > though (so somewhat similar to your "exposed").
> > >
> > > Also if the address never escapes?
> >
> > Yes.
>
> Then with respect to "expose" it seems GCC implements
> a superset which means it allows some behavior which
> is undefined according to the proposal. So all seems
> well with respect to this part.
>
>
> With respect to tracking provenance through integers
> some changes might be required.
>
> Let's consider this example:
>
> int x;
> int y;
> uintptr_t pi = (uintptr_t)&x;
> uintptr_t pj = (uintptr_t)&y;
>
> if (pi + 4 == pj) {
>
> int* p = (int*)pj; // can be one-after pointer of 'x'
> p[-1] = 1; // well defined?
> }
>
> If I understand correctly, a pointer obtained from
> pi + 4 would have a "anything" provenance (which is
> fine). But the pointer obtained from 'pj' would have the
> provenance of 'y' so the access to 'x' would not
> be allowed.
Correct. This is the most difficult case for us to handle
exactly also because (also valid for the proposal?)
int x;
int y;
uintptr_t pi = (uintptr_t)&x;
uintptr_t pj = (uintptr_t)&y;
if (pi + 4 == pj) {
int* p = (int*)(pi + 4); // can be one-after pointer of 'x'
p[-1] = 1; // well defined?
}
while well-handled by GCC in the written form (as you
say, pi + 4 yields "anything" provenance), GCC itself
may tranform it into the first variant by noticing
the conditional equivalence and substituting pj for
pi + 4.
> But according to the preferred version of
> our proposal, the pointer could also be used to
> access 'x' because it is also exposed.
>
> GCC could make pj have a "anything" provenance
> even though it is not modified. (This would break
> some optimization such as the one for Matlab.)
>
> Maybe one could also refine this optimization to check
> for additional conditions which rule out the case
> that there is another object the pointer could point
> to.
The only feasible solution would be to not track
provenance through non-pointers and make
conversions of non-pointers to pointers have
"anything" provenance.
The additional issue that appears here though
is that we cannot even turn (int *)(uintptr_t)p
into p anymore since with the conditional
substitution we can then still arrive at
effectively (&y)[-1] = 1 which is of course
undefined behavior.
That is, your proposal makes
((int *)(uintptr_t)&y)[-1] = 1
well-defined (if &y - 1 == &x) but keeps
(&y)[-1] = 1
as undefined which strikes me as a little bit
inconsistent. If that's true it's IMHO worth
a defect report and second consideration.
Richard.
> Best,
> Martin