https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120052
--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
void
foo (unsigned long s, long indx)
{
long counts[2][s];
#pragma omp parallel
#pragma omp masked
for (int i = 0; i < 2; i++)
counts[2][indx] = 1;
}
void
bar (unsigned long s, long indx)
{
long counts[2][s];
#pragma omp parallel shared(counts)
#pragma omp masked
for (int i = 0; i < 2; i++)
counts[2][indx] = 1;
}
void
baz (unsigned long s, long indx)
{
long counts[2][s];
#pragma omp parallel private(counts)
for (int i = 0; i < 2; i++)
counts[2][indx] = 1;
}
This is really nasty. The problem is that .UBSAN_BOUNDS calls are added too
early and as the last argument get TYPE_MAX_VALUE (TYPE_DOMAIN (array)) with 1
or 2 added to that. For VLAs that can involve expressions with SAVE_EXPR
inside of that.
Later on when seeing the DECL_EXPR of the VLA during gimplification, we
gimplify_type_sizes and change among other things that
(sizetype) ((long int) (SAVE_EXPR <if (SAVE_EXPR <s> == 0)
{
__builtin___ubsan_handle_vla_bound_not_positive (&*.Lubsan_data0,
(unsigned long) SAVE_EXPR <s>);
}
else
{
<<< Unknown tree: void_cst >>>
}, SAVE_EXPR <s>>) - 1)
into D.3570 with
s.0 = s;
if (s.0 == 0) goto <D.3566>; else goto <D.3567>;
<D.3566>:
__builtin___ubsan_handle_vla_bound_not_positive (&*.Lubsan_data0, s.0);
goto <D.3568>;
<D.3567>:
<D.3568>:
s.1 = s.0;
s.2_1 = (long int) s.1;
_2 = s.2_1 - 1;
_3 = (sizetype) _2;
D.3570 = _3;
The problem is that the .UBSAN_BOUNDS calls still refer to the SAVE_EXPR in
there and gimplification of SAVE_EXPRs inside OpenMP/OpenACC regions is
problematic - we don't know if the SAVE_EXPR is first used outside of the
OpenMP region or inside of it, all we see is a SAVE_EXPR possibly with the slot
having a VAR_DECL already. So, we can't easily e.g. firstprivatize that
artificial VAR_DECL, because we have no info on what expression first invokes
that SAVE_EXPR. It could be (as in this case) outside of the OpenMP region and
then we'd need to firstprivatize it, or it could be inside of the region and we
should not. And we can't do much when explicitly or implicitly handling the
data sharing of the VLA decl, because at that point the type sizes are
gimplified, so all we see is D.3570, and not that it was initialized to some
SAVE_EXPR or expression involving that.