http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48764
Richard Guenther <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |ASSIGNED Known to work| |4.4.4, 4.6.0 Keywords| |wrong-code Last reconfirmed| |2011.04.26 10:43:12 Ever Confirmed|0 |1 Summary|wrong-code bug in |[4.5/4.6/4.7 Regression] |gcc-4.5.x, related to |wrong-code bug in |__restrict |gcc-4.5.x, related to | |__restrict Target Milestone|--- |4.5.4 Known to fail| |4.5.2 --- Comment #1 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-04-26 10:43:12 UTC --- The bug is that we somehow think after inlining void FooBar::load(Loader&) (struct FooBar * const this, struct Loader & l) { ... <bb 2>: D.3062_2 = &this_1(D)->c1; D.3079_9 = &l_3(D)->buffer; this_11 = (struct Buffer * const restrict) D.3079_9; D.3083_12 = this_11->p; memcpy (D.3062_2, D.3083_12, 1); D.3083_13 = this_11->p; D.3082_14 = D.3083_13 + 1; this_11->p = D.3082_14; D.3063_4 = &this_1(D)->c2; D.3064_5 = &l_3(D)->D.2415; self_15 = (struct Loader &) D.3064_5; D.3087_16 = &self_15->buffer; this_17 = (struct Buffer * const restrict) D.3087_16; D.3091_18 = this_17->p; memcpy (D.3063_4, D.3091_18, 1); D.3091_19 = this_17->p; D.3090_20 = D.3091_19 + 1; this_17->p = D.3090_20; return; this_11 and this_17 only point to (different) objects. The restrict machinery should be robust against inlining effects because it should inherhit the arguments points-to set as well. In this case we have l_3(D), points-to non-local, points-to vars: { } self_15, points-to non-local, points-to vars: { } though, and we explicitly ignore those: /* If both pointers are restrict-qualified try to disambiguate with restrict information. */ if (TYPE_RESTRICT (TREE_TYPE (ptr1)) && TYPE_RESTRICT (TREE_TYPE (ptr2)) && !pt_solutions_same_restrict_base (&pi1->pt, &pi2->pt)) return false; /* Return true if both points-to solutions PT1 and PT2 for two restrict qualified pointers are possibly based on the same pointer. */ bool pt_solutions_same_restrict_base (struct pt_solution *pt1, struct pt_solution *pt2) { /* If we deal with points-to solutions of two restrict qualified pointers solely rely on the pointed-to variable bitmap intersection. For two pointers that are based on each other the bitmaps will intersect. */ if (pt1->vars_contains_restrict && pt2->vars_contains_restrict) { gcc_assert (pt1->vars && pt2->vars); return bitmap_intersect_p (pt1->vars, pt2->vars); } return true; } because all incoming restrict qualified pointers also point to NONLOCAL (so restrict would be useless if we don't ignore that fact). 4.4 handles restrict in a completely different way. 4.6 and 4.7 manage to make more must-aliasing appearant which avoids this issue to manifest in a miscompilation, but the issue itself is latent.