On Wed, Apr 17, 2019 at 4:12 PM Uecker, Martin <martin.uec...@med.uni-goettingen.de> wrote: > > Am Mittwoch, den 17.04.2019, 15:34 +0200 schrieb Richard Biener: > > On Wed, Apr 17, 2019 at 2:56 PM Uecker, Martin > > <martin.uec...@med.uni-goettingen.de> wrote: > > > > > > Am Mittwoch, den 17.04.2019, 14:41 +0200 schrieb Richard Biener: > > > > On Wed, Apr 17, 2019 at 1:53 PM Uecker, Martin > > > > <martin.uec...@med.uni-goettingen.de> 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