c++: Fix up handling of captured vars in lambdas in OpenMP clauses [PR93931]
Without the parser.c change we were ICEing on the testcase, because while the uses of the captured vars inside of the constructs were replaced with capture proxy decls, we didn't do that for decls in OpenMP clauses. With that fixed, we don't ICE anymore, but the testcase is miscompiled and FAILs at runtime. This is because the capture proxy decls have DECL_VALUE_EXPR and during gimplification we were gimplifying those to their DECL_VALUE_EXPRs. That is fine for shared vars, but for privatized ones we must not do that. So that is what the cp-gimplify.c changes do. Had to add a DECL_CONTEXT check before calling is_capture_proxy because some VAR_DECLs don't have DECL_CONTEXT set (yet) and is_capture_proxy relies on that being non-NULL always. 2020-03-19 Jakub Jelinek <jakub@redhat.com> PR c++/93931 * parser.c (cp_parser_omp_var_list_no_open): Call process_outer_var_ref on outer_automatic_var_p decls. * cp-gimplify.c (cxx_omp_disregard_value_expr): Return true also for capture proxy decls. * testsuite/libgomp.c++/pr93931.C: New test.
This commit is contained in:
parent
bb83e069eb
commit
02f7334ac9
5 changed files with 146 additions and 6 deletions
|
@ -1,3 +1,11 @@
|
|||
2020-03-19 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/93931
|
||||
* parser.c (cp_parser_omp_var_list_no_open): Call process_outer_var_ref
|
||||
on outer_automatic_var_p decls.
|
||||
* cp-gimplify.c (cxx_omp_disregard_value_expr): Return true also for
|
||||
capture proxy decls.
|
||||
|
||||
2020-03-18 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
PR c++/94147 - mangling of lambdas assigned to globals
|
||||
|
|
|
@ -2260,12 +2260,17 @@ cxx_omp_finish_clause (tree c, gimple_seq *)
|
|||
bool
|
||||
cxx_omp_disregard_value_expr (tree decl, bool shared)
|
||||
{
|
||||
return !shared
|
||||
&& VAR_P (decl)
|
||||
&& DECL_HAS_VALUE_EXPR_P (decl)
|
||||
&& DECL_ARTIFICIAL (decl)
|
||||
&& DECL_LANG_SPECIFIC (decl)
|
||||
&& DECL_OMP_PRIVATIZED_MEMBER (decl);
|
||||
if (shared)
|
||||
return false;
|
||||
if (VAR_P (decl)
|
||||
&& DECL_HAS_VALUE_EXPR_P (decl)
|
||||
&& DECL_ARTIFICIAL (decl)
|
||||
&& DECL_LANG_SPECIFIC (decl)
|
||||
&& DECL_OMP_PRIVATIZED_MEMBER (decl))
|
||||
return true;
|
||||
if (VAR_P (decl) && DECL_CONTEXT (decl) && is_capture_proxy (decl))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Fold expression X which is used as an rvalue if RVAL is true. */
|
||||
|
|
|
@ -34059,6 +34059,8 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
|
|||
token->location);
|
||||
}
|
||||
}
|
||||
if (outer_automatic_var_p (decl))
|
||||
decl = process_outer_var_ref (decl, tf_warning_or_error);
|
||||
if (decl == error_mark_node)
|
||||
;
|
||||
else if (kind != 0)
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2020-03-19 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/93931
|
||||
* testsuite/libgomp.c++/pr93931.C: New test.
|
||||
|
||||
2020-03-19 Tobias Burnus <tobias@codesourcery.com>
|
||||
|
||||
* testsuite/libgomp.c-c++-common/function-not-offloaded.c: Add
|
||||
|
|
120
libgomp/testsuite/libgomp.c++/pr93931.C
Normal file
120
libgomp/testsuite/libgomp.c++/pr93931.C
Normal file
|
@ -0,0 +1,120 @@
|
|||
// PR c++/93931
|
||||
// { dg-do run }
|
||||
// { dg-options "-O2 -std=c++14" }
|
||||
|
||||
extern "C" void abort ();
|
||||
|
||||
void
|
||||
sink (int &x)
|
||||
{
|
||||
int *volatile p;
|
||||
p = &x;
|
||||
(*p)++;
|
||||
}
|
||||
|
||||
int
|
||||
foo ()
|
||||
{
|
||||
int r = 0;
|
||||
[&r] () {
|
||||
#pragma omp parallel for reduction(+ : r)
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
r += i;
|
||||
} ();
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
bar ()
|
||||
{
|
||||
int l = 0;
|
||||
[&l] () {
|
||||
#pragma omp parallel for lastprivate (l)
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
l = i;
|
||||
} ();
|
||||
return l;
|
||||
}
|
||||
|
||||
void
|
||||
baz ()
|
||||
{
|
||||
int f = 18;
|
||||
[&f] () {
|
||||
#pragma omp parallel for firstprivate (f)
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
sink (f);
|
||||
f += 3;
|
||||
sink (f);
|
||||
if (f != 23)
|
||||
abort ();
|
||||
sink (f);
|
||||
f -= 7;
|
||||
sink (f);
|
||||
}
|
||||
} ();
|
||||
if (f != 18)
|
||||
abort ();
|
||||
}
|
||||
|
||||
int
|
||||
qux ()
|
||||
{
|
||||
int r = 0;
|
||||
[&] () {
|
||||
#pragma omp parallel for reduction(+ : r)
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
r += i;
|
||||
} ();
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
corge ()
|
||||
{
|
||||
int l = 0;
|
||||
[&] () {
|
||||
#pragma omp parallel for lastprivate (l)
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
l = i;
|
||||
} ();
|
||||
return l;
|
||||
}
|
||||
|
||||
void
|
||||
garply ()
|
||||
{
|
||||
int f = 18;
|
||||
[&] () {
|
||||
#pragma omp parallel for firstprivate (f)
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
sink (f);
|
||||
f += 3;
|
||||
sink (f);
|
||||
if (f != 23)
|
||||
abort ();
|
||||
sink (f);
|
||||
f -= 7;
|
||||
sink (f);
|
||||
}
|
||||
} ();
|
||||
if (f != 18)
|
||||
abort ();
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if (foo () != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
if (bar () != 1023)
|
||||
abort ();
|
||||
baz ();
|
||||
if (qux () != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
if (corge () != 1023)
|
||||
abort ();
|
||||
garply ();
|
||||
}
|
Loading…
Add table
Reference in a new issue