re PR c++/63248 (Crash when OpenMP target's array section handling is used with templ...
authorJakub Jelinek <jakub@redhat.com>
Thu, 18 Sep 2014 16:43:28 +0000 (18:43 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 18 Sep 2014 16:43:28 +0000 (18:43 +0200)
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.

From-SVN: r215359

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/cp/semantics.c
libgomp/ChangeLog
libgomp/testsuite/libgomp.c++/pr63248.C [new file with mode: 0644]

index 3a20e92612cd445c9110436ce9d34ff17e8ec26e..e7e0a3c785b666e1688b3eb675761edfde255c34 100644 (file)
@@ -1,3 +1,15 @@
+2014-09-18  Jakub Jelinek  <jakub@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.
+
 2014-09-18  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/62232
index b3a9c95ac609d4508a95a295353e5529e8252834..8a12713471b83b42d3cadd59369ae534a225761d 100644 (file)
@@ -14089,8 +14089,6 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
     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 ();
@@ -14103,6 +14101,22 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
       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;
+
     case OMP_TARGET_UPDATE:
       tmp = tsubst_omp_clauses (OMP_TARGET_UPDATE_CLAUSES (t), false,
                                args, complain, in_decl);
index aee92ddc1d0adac69600d79fd05c94e9b7f314b6..bcf161bd921cfd81e249219ef184f1526ee223a1 100644 (file)
@@ -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))
index ee73689e702ecb403c1cfa96e10b079378d64b67..72caab9ac8b380d3c036eaa1828355565d7c50db 100644 (file)
@@ -1,3 +1,8 @@
+2014-09-18  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/63248
+       * testsuite/libgomp.c++/pr63248.C: New test.
+
 2014-08-04  Jakub Jelinek  <jakub@redhat.com>
 
        * task.c (GOMP_taskgroup_end): If taskgroup->num_children
diff --git a/libgomp/testsuite/libgomp.c++/pr63248.C b/libgomp/testsuite/libgomp.c++/pr63248.C
new file mode 100644 (file)
index 0000000..48d3f0a
--- /dev/null
@@ -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 ();
+}