https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86259
--- Comment #29 from Martin Sebor <msebor at gcc dot gnu.org> --- (In reply to rguent...@suse.de from comment #25) > > Istr the proposal suggests a -fno-provenance option. How would we handle > these cases with that? The proposal is still being discussed and it's not clear how it will evolve or if the option will survive. I'm not sure if the handling of these cases would be consistent under the option. I imagine some would be expected to work as if whole objects were just arrays of bytes once provenance were not considered after some non-trivial pointer expression were involved, while others would still be undefined because of the array rule which is unrelated to provenance (e.g., indexing past the end of an array). I haven't absorbed the proposals enough yet to say for sure where the line is, and even the authors are still forming their opinion on some of these cases. (In reply to Bernd Edlinger from comment #26) > Hmmm, does this imply that > the "container_of" macro in linux/include/kernel.h will be broken: The macro is broken today because it relies on undefined behavior: advancing a pointer from one subobject to another. The latest revision of the proposal discusses some ideas that might make this and other similar examples work (e.g., a "function" such as a built-in that would make the compiler either lose the provenance of a pointer or assign it a different provenance without changing its value). Some people have suggested that casts might make it work. This isn't new. Just like it's not valid to take a pointer to one array and advance it to the next and dereference it, it's not valid to take a pointer to a struct member, advance it to point to another member, and then derefernce it. Given the following definition, the call f(2) is undefined and GCC eliminates the test on that basis. The same rule applies to struct members. char a[2][2]; void f (int i) { char c = a[1][0]; char *p = &a[0][i]; *p = 1; // can only change the array a[0], not a[1] if (c != a[1][0]) // folded to false because a[0][i] is only defined when i is zero __builtin_abort (); } To make it "work" this way you need to convince the compiler the two-dimensional 2 X 2 matrix is really a one dimensional 4-element array. The following works with GCC but it's still undefined so I wouldn't recommend relying on it. I imagine making the pointer volatile would always work (but it's still undefined). void g (int i) { char (*p)[4] = a; // -Wincompatible-pointer-types here char c = (*p)[2]; char *q = &(*p)[i]; *q = 1; if (c != (*p)[2]) // not folded __builtin_abort (); }