public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/redhat/heads/gcc-8-branch)] c++: Fix up handling of captured vars in lambdas in OpenMP clauses [PR93931]
@ 2020-09-17 17:20 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2020-09-17 17:20 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:bc5af93385c2f85dc8747b234a271cac113385c8

commit bc5af93385c2f85dc8747b234a271cac113385c8
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Thu Mar 19 12:22:47 2020 +0100

    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.
    
    (cherry picked from commit 484206967f958fc47827a71654fe52a98adc95cb)

Diff:
---
 gcc/cp/cp-gimplify.c                    |  17 +++--
 gcc/cp/parser.c                         |   2 +
 libgomp/testsuite/libgomp.c++/pr93931.C | 120 ++++++++++++++++++++++++++++++++
 3 files changed, 133 insertions(+), 6 deletions(-)

diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index dc946b9c682..113a46a156c 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -2101,12 +2101,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.  */
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index a891b1773b8..70fc1c89019 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -31684,6 +31684,8 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
 	    cp_parser_name_lookup_error (parser, name, decl, NLE_NULL,
 					 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)
diff --git a/libgomp/testsuite/libgomp.c++/pr93931.C b/libgomp/testsuite/libgomp.c++/pr93931.C
new file mode 100644
index 00000000000..4d4232ef340
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/pr93931.C
@@ -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 ();
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-09-17 17:20 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-17 17:20 [gcc(refs/vendors/redhat/heads/gcc-8-branch)] c++: Fix up handling of captured vars in lambdas in OpenMP clauses [PR93931] Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).