https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65892
--- Comment #38 from rguenther at suse dot de <rguenther at suse dot de> --- On Fri, 20 Apr 2018, msebor at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65892 > > --- Comment #35 from Martin Sebor <msebor at gcc dot gnu.org> --- > Here are the proposed changes: > > Pointer Provenance: > http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2219.htm#proposed-technical-corrigendum Mostly sound. It seems to mirror what GCC does in points-to analysis, also tracking pointers through integer (parts). I wonder about the Unary arithmetic operator restriction - consider 'long p' with single provenance, then +p has empty provenance. That's just odd. I'd have expected for example -(-p) to have the same provenance as p. GCC just uses the same provenance as the operand for unary operators. GCC also tracks provenance through floating-poing values (yes! matlab generated code passes pointers through two FP parameters...). The clarification to 6.5.9#6 is most welcome since it matches what GCC expects (and GCC doesn't implement -fno-provenance - well, I guess you could use -fno[-ipa]-pta. > Trap Representations: > http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2220.htm#proposed-technical-corrigendum Not sure what the proposed change to 6.3.2.1p2 means (if there's similar wording when actually "reading" an uninitialized value elsewhere). Iff that makes reads from uninitialized memory well-defined I miss the definition of said well-defined behavior. In any case removing the dependence on address-taken or not is good. Instead of making it explicitely defined maybe remove this sentence. For 6.3.1.2 I'd say 'the behavior is undefined' instead of 'an unspecified value'. What's the reason to be not specific here when one doesn't want 'undefined' behavior? In particular in the light of 3.19.3 if the _Bool is a trap representation then this looks suspicious. So the idea is to make uninitialized reads return unspecified values but not invoke undefined behavior. Offhand I don't know a place where GCC would take advantage of the difference. I think for both we can derive 1 == uninitialized to be true or false statically as we like but we cannot infer a path to be not taken when it would access an uninitialized location (I think we don't do that at the moment). The change doesn't require us to compute x == x to true if x is uninitialized? > Unspecified Values: > http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2221.htm#proposed-technical-corrigendum So for 3.4 GCC implements a more strict handling for example treating a * <unspecified> as not undefined given there's a value of a (zero) where the expression is fully defined. So with 3.4 '0 + <unspecified>' invokes undefined behavior? That seems to contradict the proposed wording - there isn't any value of <unspecified> where the add invokes undefined behavior. More to the point why do they introduce undefined behavior here rather than an unspecified value? This means that <unspecified> on it's own is fine to use but computing <unspecified> + <unspecified> is not. And in 3.5 they go on and specify '0 * <unspecified>' as unspecified?! So I think they go a bit too far here on several accounts. I'd like to keep reading from uninitialized memory invoking undefined behavior - if it's just unspecified how are sanitizers supposed to handle this given the compiler is now free to schedule such reads to places where they might not have been executed before. The changes do not seem to cover effective types and aliasing as far as I can see (or I missed a non-linked proposed corrigendum). N2222 doesn't seem to have any.