When compiling the attached source code with -Wall -O3 -UWARN, no warning on type punning is printed. If I compile with -Wall -O3 -DWARN, a warning is printed. ff.C:31: warning: dereferencing type-punned pointer will break strict-aliasing rules While in the attached example, everything seems to work fine, my application crashes. Would it be feasible to print the warning also for the nested function calls ?
Created attachment 16884 [details] Source code which illustrates the problem.
The complication is that we "optimize" the code into a form that no longer violates aliasing rules which effectively disables the warning that happens after inlining. IMHO we can issue alias warnings from the code that propagates (const struct Func &) &D.1753 into *D.1793_4 (tree forwprop) if and if only the propagation result is a VIEW_CONVERT_EXPR and its base object does not contain a pointer dereference. In turn further propagations of invariant addresses into that VIEW_CONVERT_EXPR may then raise the warning instead. Note that this is really a middle-end issue, IMHO the FE based warnings should be disabled if optimization is enabled as they warn on conversions and not pointer dereferences thus giving too many false positives anyway.
This is what I get for trying to get better optimizations in the first place :). Maybe we should warn when we do the VCE conversion if the aliasing sets don't match?
Yes. Though you have to be careful not to create false positives for float f; struct X { int i; }; struct X *p = (struct X *)&f; float *q = (float *)&p->i; return *q; if the code is obfuscated enough that the definition of p is not visible. Or, one could even say that creating VIEW_CONVERT_EXPR <float> (p->i) is an invalid transformation and causes an alias violation. Do we do this transformation in this case? I think we should avoid doing it here (that is, whenever the expression we view-convert contains a pointer dereference).
(In reply to comment #4) > Yes. Though you have to be careful not to create false positives for > > float f; > struct X { int i; }; > > struct X *p = (struct X *)&f; > float *q = (float *)&p->i; > return *q; Actually that is an aliasing violation still as you still accessing *p, yes it looks like it is not an access because of the address but you are still accessing *p really.
(In reply to comment #5) > Actually that is an aliasing violation still as you still accessing *p, yes it > looks like it is not an access because of the address but you are still > accessing *p really. Oh and we do create a VCE for that case already: return VIEW_CONVERT_EXPR<int>(a->a); Yes we thought about this when I was writing the original code which created the VCE. If it was just (float*)p, there would be no aliasing violation but the access happens even if memory is not really accessed. The address expression still does not cause no access to happen, this is why doing (int)(&((struct f*)(0))->a) is still undefined code as there is an access to a NULL pointer (even if we supported this access).
Even if I cannot find the proper section of the standard that says &a->b is not considered an access it does make sense for GIMPLE to do so. Otherwise we cannot transform (char *)a + 4 to &a->b because the latter would be a (possibly invalid) access while the former is not. So, we definitely should _not_ generate a V_C_E here.
Are there any news on this guy here ? I am really having a hard time porting my project to GCC 4.3 as I have a big source file which seems to do a lot of type punning, but I get no warnings. Depending on the compile options I get crashes. Or should I just turn off strict aliasing for this source file to be on the safe side.
Mine.
Note that I am going to fix the missing warning because of comment #2 only. For 4.3 comment #2 does not apply, instead you get a warning with -Wstrict-aliasing=1 g++-4.3 -Wall -O3 -S t.C -UWARN -fdump-tree-all -Wstrict-aliasing=1 t.C: In function ‘Term term(const Func&)’: t.C:13: warning: dereferencing type-punned pointer might break strict-aliasing rules t.C: In function ‘const Func& func(const Term&)’: t.C:23: warning: dereferencing type-punned pointer might break strict-aliasing rules