https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102698

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Just one extra note:
    !$omp atomic capture
    x(idx(i), idy(i)) = ior(x(idx(i), idy(i)), fun(i))
    o(idx(i), idy(i)) = x(idx(i), idy(i))
    !$omp end atomic
is really (under the hood):
    temp_expr = fun(i)
    !$omp atomic capture
    x(idx(i), idy(i)) = ior(x(idx(i), idy(i)), temp_expr)
    temp_v = x(idx(i), idy(i))
    !$omp end atomic
    o(idx(i), idy(i)) = temp_v
and if you write it that way, it is more obvious your program is racy.
Even the x(idx(i), idy(i)) expression gets its address evaluated once before
the construct (if it has some side-effects) and then it is just
__atomic_or_fetch on that address.

Reply via email to