On Thu, 18 Apr 2019 at 10:32, 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.
In the proposed semantics, the integers have no provenance info at all, so pj and pi+4 are interchangeable inside the conditional. An equality test of two pointers, on the other hand, doesn't necessarily mean that they are interchangeable. I don't see any good way to avoid that in a provenance semantics, where a one-past pointer might sometimes compare equal to a pointer to an adjacent object but be illegal for accessing it. > > 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 that's true (if x has been exposed). >which strikes me as a little bit > inconsistent. If that's true it's IMHO worth > a defect report and second consideration. There's a trade-off here. We could permit roundtrips of pointer-to-integer-to-pointer only recover provenance if the pointer is properly within the object, giving empty provenance for a one-past pointer. That would fix the above, but it's not clear whether this would be a bad restriction for existing code. best, Peter > Richard. > > > Best, > > Martin