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.