Hi!

For firstprivate vars, even when implicit, the privatized entity is
what the reference refers to; if its copy ctor or dtor need instantiation,
doing this at gimplification time is too late, therefore we should handle
it during genericization like we handle non-reference firstprivatized vars.

Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk,
queued for backporting.

2017-09-14  Jakub Jelinek  <ja...@redhat.com>

        PR c++/81314
        * cp-gimplify.c (omp_var_to_track): Look through references.
        (omp_cxx_notice_variable): Likewise.

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

--- gcc/cp/cp-gimplify.c.jj     2017-09-01 09:26:24.000000000 +0200
+++ gcc/cp/cp-gimplify.c        2017-09-14 15:31:54.526100238 +0200
@@ -895,6 +895,8 @@ omp_var_to_track (tree decl)
   tree type = TREE_TYPE (decl);
   if (is_invisiref_parm (decl))
     type = TREE_TYPE (type);
+  else if (TREE_CODE (type) == REFERENCE_TYPE)
+    type = TREE_TYPE (type);
   while (TREE_CODE (type) == ARRAY_TYPE)
     type = TREE_TYPE (type);
   if (type == error_mark_node || !CLASS_TYPE_P (type))
@@ -947,6 +949,8 @@ omp_cxx_notice_variable (struct cp_gener
              tree type = TREE_TYPE (decl);
              if (is_invisiref_parm (decl))
                type = TREE_TYPE (type);
+             else if (TREE_CODE (type) == REFERENCE_TYPE)
+               type = TREE_TYPE (type);
              while (TREE_CODE (type) == ARRAY_TYPE)
                type = TREE_TYPE (type);
              get_copy_ctor (type, tf_none);
--- libgomp/testsuite/libgomp.c++/pr81314.C.jj  2017-09-14 15:51:17.883604562 
+0200
+++ libgomp/testsuite/libgomp.c++/pr81314.C     2017-09-14 15:50:56.000000000 
+0200
@@ -0,0 +1,38 @@
+// PR c++/81314
+// { dg-do link }
+
+template <int N>
+struct S {
+  S () { s = 0; }
+  S (const S &x) { s = x.s; }
+  ~S () {}
+  int s;
+};
+
+void
+foo (S<2> &x)
+{
+  #pragma omp taskloop
+  for (int i = 0; i < 100; ++i)
+    x.s++;
+}
+
+void
+bar (S<3> &x)
+{
+  #pragma omp task
+  x.s++;
+}
+
+int
+main ()
+{
+  S<2> s;
+  S<3> t;
+  #pragma omp parallel
+  #pragma omp master
+  {
+    foo (s);
+    bar (t);
+  }
+}

        Jakub

Reply via email to