On Wed, Sep 10, 2014 at 05:21:07PM +0200, Thomas Schwinge wrote:
> Hi!
> 
> On Wed, 10 Sep 2014 12:23:04 +0200, Jakub Jelinek <ja...@redhat.com> wrote:
> > On Wed, Sep 10, 2014 at 12:12:03PM +0200, Thomas Schwinge wrote:
> > > Are the following issues known?
> > 
> > No, please file a PR.
> 
> Will do tomorrow.

Here is a fix I've committed to trunk/4.9 after testing on x86_64-linux.

2014-09-18  Jakub Jelinek  <ja...@redhat.com>

        PR c++/63248
        * semantics.c (finish_omp_clauses): Don't call cp_omp_mappable_type
        on type of type dependent expressions, and don't call it if
        handle_omp_array_sections has kept TREE_LIST because something
        was type dependent.
        * pt.c (tsubst_expr) <case OMP_TARGET, case OMP_TARGET_DATA>:
        Use keep_next_level, begin_omp_structured_block and
        finish_omp_structured_block instead of push_stmt_list and
        pop_stmt_list.
libgomp/
        * testsuite/libgomp.c++/pr63248.C: New test.

--- gcc/cp/semantics.c.jj       2014-09-17 21:01:11.000000000 +0200
+++ gcc/cp/semantics.c  2014-09-18 17:05:19.785988633 +0200
@@ -5668,7 +5668,9 @@ finish_omp_clauses (tree clauses)
              else
                {
                  t = OMP_CLAUSE_DECL (c);
-                 if (!cp_omp_mappable_type (TREE_TYPE (t)))
+                 if (TREE_CODE (t) != TREE_LIST
+                     && !type_dependent_expression_p (t)
+                     && !cp_omp_mappable_type (TREE_TYPE (t)))
                    {
                      error_at (OMP_CLAUSE_LOCATION (c),
                                "array section does not have mappable type "
@@ -5708,6 +5710,7 @@ finish_omp_clauses (tree clauses)
            remove = true;
          else if (!(OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
                     && OMP_CLAUSE_MAP_KIND (c) == OMP_CLAUSE_MAP_POINTER)
+                  && !type_dependent_expression_p (t)
                   && !cp_omp_mappable_type ((TREE_CODE (TREE_TYPE (t))
                                              == REFERENCE_TYPE)
                                             ? TREE_TYPE (TREE_TYPE (t))
--- gcc/cp/pt.c.jj      2014-09-16 10:00:35.000000000 +0200
+++ gcc/cp/pt.c 2014-09-18 18:12:09.804850925 +0200
@@ -14089,8 +14089,6 @@ tsubst_expr (tree t, tree args, tsubst_f
     case OMP_SECTIONS:
     case OMP_SINGLE:
     case OMP_TEAMS:
-    case OMP_TARGET_DATA:
-    case OMP_TARGET:
       tmp = tsubst_omp_clauses (OMP_CLAUSES (t), false,
                                args, complain, in_decl);
       stmt = push_stmt_list ();
@@ -14099,6 +14097,22 @@ tsubst_expr (tree t, tree args, tsubst_f
 
       t = copy_node (t);
       OMP_BODY (t) = stmt;
+      OMP_CLAUSES (t) = tmp;
+      add_stmt (t);
+      break;
+
+    case OMP_TARGET_DATA:
+    case OMP_TARGET:
+      tmp = tsubst_omp_clauses (OMP_CLAUSES (t), false,
+                               args, complain, in_decl);
+      keep_next_level (true);
+      stmt = begin_omp_structured_block ();
+
+      RECUR (OMP_BODY (t));
+      stmt = finish_omp_structured_block (stmt);
+
+      t = copy_node (t);
+      OMP_BODY (t) = stmt;
       OMP_CLAUSES (t) = tmp;
       add_stmt (t);
       break;
--- libgomp/testsuite/libgomp.c++/pr63248.C.jj  2014-09-18 18:19:49.806529990 
+0200
+++ libgomp/testsuite/libgomp.c++/pr63248.C     2014-09-18 18:18:58.000000000 
+0200
@@ -0,0 +1,62 @@
+// PR c++/63248
+// { dg-do run }
+
+int *v;
+
+template <typename T>
+T
+foo (T A, T B)
+{
+  T a = 2;
+  T b = 4;
+
+#pragma omp target map(v[a:b])
+  v[a] = 1;
+
+#pragma omp target map(v[A:B])
+  v[a] = 2;
+
+#pragma omp target map(A)
+  A = 19;
+  return A;
+}
+
+template <int N>
+int
+bar (int A, int B)
+{
+#pragma omp target map(A)
+  A = 8;
+  if (A != 8)
+    __builtin_abort ();
+#pragma omp target map(A, B)
+  {
+    A = 1;
+    B = 2;
+  }
+  return A + B;
+}
+
+int
+baz (int A, int B)
+{
+#pragma omp target map(A)
+  A = 8;
+  if (A != 8)
+    __builtin_abort ();
+#pragma omp target map(A, B)
+  {
+    A = 1;
+    B = 2;
+  }
+  return A + B;
+}
+
+int
+main ()
+{
+  int a[10] = { 0 };
+  v = a;
+  if (foo (1, 5) != 19 || v[2] != 2 || bar<0> (5, 7) != 3 || baz (5, 7) != 3)
+    __builtin_abort ();
+}


        Jakub

Reply via email to