backport: re PR c/45784 (gcc OpenMP - error: invalid controlling predicate)

Backported from mainline
	2017-07-27  Jakub Jelinek  <jakub@redhat.com>

	PR c/45784
	* c-omp.c (c_finish_omp_for): If the condition is wrapped in
	rhs of COMPOUND_EXPR(s), skip them and readd their lhs into
	new COMPOUND_EXPRs around the rhs of the comparison.

	* testsuite/libgomp.c/pr45784.c: New test.
	* testsuite/libgomp.c++/pr45784.C: New test.

From-SVN: r251848
This commit is contained in:
Jakub Jelinek 2017-09-07 22:18:45 +02:00 committed by Jakub Jelinek
parent e7954201e5
commit 54e97c588a
5 changed files with 86 additions and 0 deletions

View File

@ -1,3 +1,13 @@
2017-09-07 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2017-07-27 Jakub Jelinek <jakub@redhat.com>
PR c/45784
* c-omp.c (c_finish_omp_for): If the condition is wrapped in
rhs of COMPOUND_EXPR(s), skip them and readd their lhs into
new COMPOUND_EXPRs around the rhs of the comparison.
2017-08-14 Release Manager
* GCC 7.2.0 released.

View File

@ -531,6 +531,12 @@ c_finish_omp_for (location_t locus, enum tree_code code, tree declv,
{
bool cond_ok = false;
/* E.g. C sizeof (vla) could add COMPOUND_EXPRs with
evaluation of the vla VAR_DECL. We need to readd
them to the non-decl operand. See PR45784. */
while (TREE_CODE (cond) == COMPOUND_EXPR)
cond = TREE_OPERAND (cond, 1);
if (EXPR_HAS_LOCATION (cond))
elocus = EXPR_LOCATION (cond);
@ -605,6 +611,21 @@ c_finish_omp_for (location_t locus, enum tree_code code, tree declv,
else if (code != CILK_SIMD && code != CILK_FOR)
cond_ok = false;
}
if (cond_ok && TREE_VEC_ELT (condv, i) != cond)
{
tree ce = NULL_TREE, *pce = &ce;
tree type = TREE_TYPE (TREE_OPERAND (cond, 1));
for (tree c = TREE_VEC_ELT (condv, i); c != cond;
c = TREE_OPERAND (c, 1))
{
*pce = build2 (COMPOUND_EXPR, type, TREE_OPERAND (c, 0),
TREE_OPERAND (cond, 1));
pce = &TREE_OPERAND (*pce, 1);
}
TREE_OPERAND (cond, 1) = ce;
TREE_VEC_ELT (condv, i) = cond;
}
}
if (!cond_ok)

View File

@ -1,3 +1,12 @@
2017-09-07 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2017-07-27 Jakub Jelinek <jakub@redhat.com>
PR c/45784
* testsuite/libgomp.c/pr45784.c: New test.
* testsuite/libgomp.c++/pr45784.C: New test.
2017-08-14 Release Manager
* GCC 7.2.0 released.

View File

@ -0,0 +1,5 @@
// PR c/45784
// { dg-do run }
#include "../libgomp.c/pr45784.c"

View File

@ -0,0 +1,41 @@
/* PR c/45784 */
/* { dg-do run } */
void
foo (int n)
{
char *p, vla[2 * n];
int i;
#pragma omp parallel for
for (p = vla; p < vla + (sizeof (vla) / sizeof (vla[0])); p++)
*p = ' ';
#pragma omp parallel for
for (i = 0; i < 2 * n; i++)
if (vla[i] != ' ')
__builtin_abort ();
}
void
bar (int n)
{
char *p, vla1[n], vla2[n * 2], vla3[n * 3], vla4[n * 4];
int i;
__builtin_memset (vla4, ' ', n * 4);
#pragma omp parallel for
for (p = vla4 + sizeof (vla1); p < vla4 + sizeof (vla3) - sizeof (vla2) + sizeof (vla1); p += sizeof (vla4) / sizeof (vla4))
p[0] = '!';
#pragma omp parallel for
for (i = 0; i < n * 4; i++)
if (vla4[i] != ((i >= n && i < 2 * n) ? '!' : ' '))
__builtin_abort ();
}
int
main ()
{
volatile int n;
n = 128;
foo (n);
bar (n);
return 0;
}