On Thu, 18 Apr 2019 at 10:56, Richard Biener <richard.guent...@gmail.com> wrote: > > On Thu, Apr 18, 2019 at 11:31 AM Richard Biener > <richard.guent...@gmail.com> wrote: > > > > 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. > > Similarly that > > int x; > int y; > uintptr_t pj = (uintptr_t)&y; > > if (&x + 1 == &y) { > > int* p = (int*)pj; // can be one-after pointer of 'x' > p[-1] = 1; // well defined? > } > > is undefined but when I add a no-op > > (uintptr_t)&x; > > it is well-defined is undesirable. Can this no-op > stmt appear in another function? Or even in > another translation unit (if x and y are global variables)? > And does such stmt have to be present (in another > TU) to make the example valid in this case?
yes to all that - again, in the variant in which roundtrips of a one-past pointer are supported. > To me all this makes requiring exposal through a cast > to a non-pointer (or accessing its representation) not > in any way more "useful" for an optimizing compiler than > modeling exposal through address-taking. interesting, thanks best, Peter > Richard. > > > Richard. > > > > > Best, > > > Martin