The following testcase emits a strict-aliasing warning because the points-to result for p is wrong. It should be pt_anything, but instead the read from s.q is considered a non-pointer variable (we do not have constraints for all implicitly taken addresses by passing &s to the function call). struct S { int *p; int *q; }; void foo (struct S *); int bar (int b) { struct S s; int *p; float f; foo (&s); if (b) p = s.q; else p = (int *)&f; return *p; } Inspecting the points-to results on struct S { int *p; int *q; }; void foo (struct S *); int *bar (int b) { struct S s; foo (&s); return s.q; } exposes the failure as ESCAPED = { ESCAPED NONLOCAL s s.64+64 } ... s = { ESCAPED NONLOCAL } s.64+64 = { ESCAPED NONLOCAL } D.1598_1 = { } D.1598_1 should have the same solution as s.64+64.
It is interesting to see how taking the address of &s.q makes it a pointer variable. The fundamental issue seems to be that eliminating non-pointers and their edges conflicts with field-sensitive analysis. Consider struct S { int *p; int *q; }; void foo (struct S **); int *bar (int b) { struct S s; struct S *p = &s; foo (&p); return s.q; } to see that just generating extra ADDRESSOF constraints for call arguments will not fix the issue. Not only we will need to avoid eliminating non-pointers / edges if any of a variables sub-field has got a proper pointer label, unifying them (they still have pointer label 0) is also wrong. Danny, any idea where/how to fix this?
In fact, field-sensitive points-to analysis is probably not improving things anyway - a testcase where it does is certainly welcome! - simply due to the fact that the points-to analysis would need to be more clever than load (partial-)redundancy elimination. Where it could help is for IPA mode though. And likely it will rot very quickly if we disable it, but ... disabling it would be my prefered choice here.
Subject: Re: points-to result wrong for reads from call-clobbered vars Interesting. I have emailed some others for their thoughts. One way to eliminate this bug would be to mark the entire structure as indirect nodes due to &s when we initialize the offline problem. You would also have to do the same if you see &s.p. The problem of course, is that i think our C++ implementation still plays games with subtracting offsets, so for C++, you'd have to mark the entire structure full of variables indirect when you see address taking of any member :( Anyway, give me a short time to wait for responses and see if there is a good way out of this. On Tue, Jan 13, 2009 at 7:34 AM, rguenth at gcc dot gnu dot org <gcc-bugzilla@gcc.gnu.org> wrote: > > > ------- Comment #1 from rguenth at gcc dot gnu dot org 2009-01-13 12:34 ------- > It is interesting to see how taking the address of &s.q makes it a pointer > variable. The fundamental issue seems to be that eliminating non-pointers > and their edges conflicts with field-sensitive analysis. > > Consider > > struct S { int *p; int *q; }; > > void foo (struct S **); > > int *bar (int b) > { > struct S s; > struct S *p = &s; > foo (&p); > return s.q; > } > > to see that just generating extra ADDRESSOF constraints for call arguments > will not fix the issue. > > Not only we will need to avoid eliminating non-pointers / edges if any of a > variables sub-field has got a proper pointer label, unifying them (they > still have pointer label 0) is also wrong. > > Danny, any idea where/how to fix this? > > > -- > > rguenth at gcc dot gnu dot org changed: > > What |Removed |Added > ---------------------------------------------------------------------------- > CC| |dberlin at gcc dot gnu dot > | |org > > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38826 > > ------- You are receiving this mail because: ------- > You are on the CC list for the bug, or are watching someone who is. >
Subject: Bug 38826 Author: rguenth Date: Wed Jan 14 16:45:22 2009 New Revision: 143374 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=143374 Log: 2009-01-14 Richard Guenther <rguenther@suse.de> PR tree-optimization/38826 PR middle-end/38477 * tree-ssa-structalias.c (emit_alias_warning): Emit the pointer initialization notes only if we actually emitted a warning. (intra_create_variable_infos): Add constraints for a result decl that is passed by hidden reference. (build_pred_graph): Mark all related variables non-direct on address-taking. * gcc.dg/Wstrict-aliasing-bogus-pta-1.c: New testcase. Added: trunk/gcc/testsuite/gcc.dg/Wstrict-aliasing-bogus-pta-1.c Modified: trunk/gcc/ChangeLog trunk/gcc/testsuite/ChangeLog trunk/gcc/tree-ssa-structalias.c
Fixed.