On Wed, Jun 10, 2015 at 11:38:25AM +0000, Joseph Myers wrote:
> This patch, for gomp-4_0-branch, adds support for C++ "this" in
> OpenACC directives.  (This patch does not do anything to handle OpenMP
> differently from OpenACC; that - bug 66053 - will need to be resolved
> for mainline, either deciding these cases should be accepted for
> OpenMP or making the parsing only accept them in OpenACC directives
> and not OpenMP ones.)

So, OpenMP 4.1 is going to accept this only in linear/uniform/aligned
clauses and only in #pragma omp declare simd construct.

This patch implements this, but as there is no oacc argument to
finish_omp_clauses on the trunk/gomp-4_1-branch, I haven't used that
to allow it in OpenACC directives, so that will need to be resolved
when the branches are merged to trunk.

Note I'm afraid your gomp-4_0-branch patch will not do the right thing
if you use this outside of non-static member functions (which is why I've
added the finish_this_expr for diagnostics).

Anyway, committed to gomp4.1 branch.

2015-07-09  Jakub Jelinek  <ja...@redhat.com>

        * parser.c (cp_parser_omp_var_list_no_open): Parse this.
        * cp-tree.h (finish_omp_declare_simd_methods): New prototype.
        * semantics.c (handle_omp_array_sections_1): Disallow this based
        array sections for OpenMP.
        (finish_omp_declare_simd_methods): New function.
        (finish_omp_clauses): Don't attempt to adjust linear step of
        this if it points to TYPE_BEING_DEFINED.  Disallow this in
        all clauses expecting variable lists, except for declare simd
        linear/uniform/aligned clauses.
        (finish_struct_1): Call finish_omp_declare_simd_methods.

        * g++.dg/vect/simd-clone-2.cc: New test.
        * g++.dg/vect/simd-clone-2.h: New file.
        * g++.dg/vect/simd-clone-3.cc: New test.
        * g++.dg/vect/simd-clone-4.cc: New test.
        * g++.dg/vect/simd-clone-4.h: New file.
        * g++.dg/vect/simd-clone-5.cc: New test.
        * g++.dg/gomp/this-1.C: New test.
        * g++.dg/gomp/this-2.C: New test.

--- gcc/cp/parser.c.jj  2015-07-06 13:42:22.000000000 +0200
+++ gcc/cp/parser.c     2015-07-08 11:33:17.255688547 +0200
@@ -27881,15 +27881,26 @@ cp_parser_omp_var_list_no_open (cp_parse
       tree name, decl;
 
       token = cp_lexer_peek_token (parser->lexer);
-      name = cp_parser_id_expression (parser, /*template_p=*/false,
-                                     /*check_dependency_p=*/true,
-                                     /*template_p=*/NULL,
-                                     /*declarator_p=*/false,
-                                     /*optional_p=*/false);
-      if (name == error_mark_node)
-       goto skip_comma;
+      if (current_class_ptr && cp_parser_is_keyword (token, RID_THIS))
+       {
+         decl = finish_this_expr ();
+         if (TREE_CODE (decl) == NON_LVALUE_EXPR
+             || CONVERT_EXPR_P (decl))
+           decl = TREE_OPERAND (decl, 0);
+         cp_lexer_consume_token (parser->lexer);
+       }
+      else
+       {
+         name = cp_parser_id_expression (parser, /*template_p=*/false,
+                                         /*check_dependency_p=*/true,
+                                         /*template_p=*/NULL,
+                                         /*declarator_p=*/false,
+                                         /*optional_p=*/false);
+         if (name == error_mark_node)
+           goto skip_comma;
 
-      decl = cp_parser_lookup_name_simple (parser, name, token->location);
+         decl = cp_parser_lookup_name_simple (parser, name, token->location);
+       }
       if (decl == error_mark_node)
        cp_parser_name_lookup_error (parser, name, decl, NLE_NULL,
                                     token->location);
--- gcc/cp/cp-tree.h.jj 2015-07-01 12:50:49.000000000 +0200
+++ gcc/cp/cp-tree.h    2015-07-08 17:27:02.787472523 +0200
@@ -5998,6 +5998,7 @@ extern void note_decl_for_pch                     (tree);
 extern tree omp_reduction_id                   (enum tree_code, tree, tree);
 extern tree cp_remove_omp_priv_cleanup_stmt    (tree *, int *, void *);
 extern void cp_check_omp_declare_reduction     (tree);
+extern void finish_omp_declare_simd_methods    (tree);
 extern tree finish_omp_clauses                 (tree, bool, bool = false);
 extern tree push_omp_privatization_clauses     (bool);
 extern void pop_omp_privatization_clauses      (tree);
--- gcc/cp/semantics.c.jj       2015-07-06 19:20:51.000000000 +0200
+++ gcc/cp/semantics.c  2015-07-08 19:26:01.837813436 +0200
@@ -4390,6 +4390,15 @@ handle_omp_array_sections_1 (tree c, tre
                      omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
          return error_mark_node;
        }
+      else if (TREE_CODE (t) == PARM_DECL
+              && DECL_ARTIFICIAL (t)
+              && DECL_NAME (t) == this_identifier)
+       {
+         error_at (OMP_CLAUSE_LOCATION (c),
+                   "%<this%> allowed in OpenMP only in %<declare simd%>"
+                   " clauses");
+         return error_mark_node;
+       }
       else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
               && VAR_P (t) && DECL_THREAD_LOCAL_P (t))
        {
@@ -5491,6 +5500,39 @@ finish_omp_reduction_clause (tree c, boo
   return false;
 }
 
+/* Called from finish_struct_1.  linear(this) or linear(this:step)
+   clauses might not be finalized yet because the class has been incomplete
+   when parsing #pragma omp declare simd methods.  Fix those up now.  */
+
+void
+finish_omp_declare_simd_methods (tree t)
+{
+  if (processing_template_decl)
+    return;
+
+  for (tree x = TYPE_METHODS (t); x; x = DECL_CHAIN (x))
+    {
+      if (TREE_CODE (TREE_TYPE (x)) != METHOD_TYPE)
+       continue;
+      tree ods = lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (x));
+      if (!ods || !TREE_VALUE (ods))
+       continue;
+      for (tree c = TREE_VALUE (TREE_VALUE (ods)); c; c = OMP_CLAUSE_CHAIN (c))
+       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
+           && integer_zerop (OMP_CLAUSE_DECL (c))
+           && OMP_CLAUSE_LINEAR_STEP (c)
+           && TREE_CODE (TREE_TYPE (OMP_CLAUSE_LINEAR_STEP (c)))
+              == POINTER_TYPE)
+         {
+           tree s = OMP_CLAUSE_LINEAR_STEP (c);
+           s = fold_convert_loc (OMP_CLAUSE_LOCATION (c), sizetype, s);
+           s = fold_build2_loc (OMP_CLAUSE_LOCATION (c), MULT_EXPR,
+                                sizetype, s, TYPE_SIZE_UNIT (t));
+           OMP_CLAUSE_LINEAR_STEP (c) = s;
+         }
+    }
+}
+
 /* For all elements of CLAUSES, validate them vs OpenMP constraints.
    Remove any elements from the list that are invalid.  */
 
@@ -5626,7 +5668,15 @@ finish_omp_clauses (tree clauses, bool a
                          break;
                        }
                    }
-                 else if (TREE_CODE (type) == POINTER_TYPE)
+                 else if (TREE_CODE (type) == POINTER_TYPE
+                          /* Can't multiply the step yet if *this
+                             is still incomplete type.  */
+                          && (!declare_simd
+                              || TREE_CODE (OMP_CLAUSE_DECL (c)) != PARM_DECL
+                              || !DECL_ARTIFICIAL (OMP_CLAUSE_DECL (c))
+                              || DECL_NAME (OMP_CLAUSE_DECL (c))
+                                 != this_identifier
+                              || !TYPE_BEING_DEFINED (TREE_TYPE (type))))
                    {
                      tree d = convert_from_reference (OMP_CLAUSE_DECL (c));
                      t = pointer_int_sum (OMP_CLAUSE_LOCATION (c), PLUS_EXPR,
@@ -5655,6 +5705,16 @@ finish_omp_clauses (tree clauses, bool a
          else
            t = OMP_CLAUSE_DECL (c);
        check_dup_generic_t:
+         if (t == current_class_ptr
+             && (!declare_simd
+                 || (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LINEAR
+                     && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_UNIFORM)))
+           {
+             error ("%<this%> allowed in OpenMP only in %<declare simd%>"
+                    " clauses");
+             remove = true;
+             break;
+           }
          if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL
              && (!field_ok || TREE_CODE (t) != FIELD_DECL))
            {
@@ -5696,6 +5756,13 @@ finish_omp_clauses (tree clauses, bool a
            omp_note_field_privatization (t, OMP_CLAUSE_DECL (c));
          else
            t = OMP_CLAUSE_DECL (c);
+         if (t == current_class_ptr)
+           {
+             error ("%<this%> allowed in OpenMP only in %<declare simd%>"
+                    " clauses");
+             remove = true;
+             break;
+           }
          if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL
              && (!allow_fields || TREE_CODE (t) != FIELD_DECL))
            {
@@ -5723,6 +5790,13 @@ finish_omp_clauses (tree clauses, bool a
            omp_note_field_privatization (t, OMP_CLAUSE_DECL (c));
          else
            t = OMP_CLAUSE_DECL (c);
+         if (t == current_class_ptr)
+           {
+             error ("%<this%> allowed in OpenMP only in %<declare simd%>"
+                    " clauses");
+             remove = true;
+             break;
+           }
          if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL
              && (!allow_fields || TREE_CODE (t) != FIELD_DECL))
            {
@@ -6000,6 +6074,13 @@ finish_omp_clauses (tree clauses, bool a
 
        case OMP_CLAUSE_ALIGNED:
          t = OMP_CLAUSE_DECL (c);
+         if (t == current_class_ptr && !declare_simd)
+           {
+             error ("%<this%> allowed in OpenMP only in %<declare simd%>"
+                    " clauses");
+             remove = true;
+             break;
+           }
          if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
            {
              if (processing_template_decl)
@@ -6086,6 +6167,12 @@ finish_omp_clauses (tree clauses, bool a
                error ("%qE is not a variable in %<depend%> clause", t);
              remove = true;
            }
+         else if (t == current_class_ptr)
+           {
+             error ("%<this%> allowed in OpenMP only in %<declare simd%>"
+                    " clauses");
+             remove = true;
+           }
          else if (!processing_template_decl
                   && !cxx_mark_addressable (t))
            remove = true;
@@ -6139,6 +6226,13 @@ finish_omp_clauses (tree clauses, bool a
                     omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
              remove = true;
            }
+         else if (t == current_class_ptr)
+           {
+             error ("%<this%> allowed in OpenMP only in %<declare simd%>"
+                    " clauses");
+             remove = true;
+             break;
+           }
          else if (!processing_template_decl
                   && TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE
                   && !cxx_mark_addressable (t))
--- gcc/cp/class.c.jj   2015-06-30 14:25:15.000000000 +0200
+++ gcc/cp/class.c      2015-07-08 17:06:57.182745066 +0200
@@ -6651,6 +6651,8 @@ finish_struct_1 (tree t)
 
   finish_struct_bits (t);
   set_method_tm_attributes (t);
+  if (flag_openmp || flag_openmp_simd)
+    finish_omp_declare_simd_methods (t);
 
   /* Complete the rtl for any static member objects of the type we're
      working on.  */
--- gcc/testsuite/g++.dg/vect/simd-clone-2.cc.jj        2015-07-08 
18:05:43.898418797 +0200
+++ gcc/testsuite/g++.dg/vect/simd-clone-2.cc   2015-07-08 18:34:57.039683991 
+0200
@@ -0,0 +1,55 @@
+// { dg-require-effective-target vect_simd_clones }
+// { dg-additional-options "-fopenmp-simd -fno-inline -DONE_FILE" }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+
+#include "../../gcc.dg/vect/tree-vect.h"
+
+#ifdef ONE_FILE
+#include "simd-clone-3.cc"
+#else
+#include "simd-clone-2.h"
+#endif
+
+T b __attribute__((aligned (32)));
+
+void
+do_main ()
+{
+  int i, r = 0;
+  S a[64];
+  for (i = 0; i < 64; i++)
+    {
+      a[i].s = i;
+      b.t[i] = i;
+    }
+  #pragma omp simd reduction(+:r)
+  for (i = 0; i < 64; i++)
+    r += a[16].f0 (i);
+  if (r != 64 * 63 / 2 + 64 * 16)
+    __builtin_abort ();
+  r = 0;
+  #pragma omp simd reduction(+:r)
+  for (i = 0; i < 64; i++)
+    r += a[32].f1 (i);
+  if (r != 64 * 63 / 2 + 64 * 32)
+    __builtin_abort ();
+  r = 0;
+  #pragma omp simd reduction(+:r)
+  for (i = 0; i < 64; i++)
+    r += a[i].f2 (i);
+  if (r != 64 * 63)
+    __builtin_abort ();
+  r = 0;
+  #pragma omp simd reduction(+:r)
+  for (i = 0; i < 64; i++)
+    r += b.f3 (i);
+  if (r != 64 * 63 / 2)
+    __builtin_abort ();
+}
+
+int
+main ()
+{
+  check_vect ();
+  do_main ();
+}
--- gcc/testsuite/g++.dg/vect/simd-clone-2.h.jj 2015-07-08 18:06:14.945978075 
+0200
+++ gcc/testsuite/g++.dg/vect/simd-clone-2.h    2015-07-08 18:02:21.459292430 
+0200
@@ -0,0 +1,17 @@
+struct S
+{
+  int s;
+  #pragma omp declare simd notinbranch
+  int f0 (int x);
+  #pragma omp declare simd notinbranch uniform(this)
+  int f1 (int x);
+  #pragma omp declare simd notinbranch linear(this:sizeof(this)/sizeof(this))
+  int f2 (int x);
+};
+
+struct T
+{
+  int t[64];
+  #pragma omp declare simd aligned(this:32) uniform(this) linear(x)
+  int f3 (int x);
+};
--- gcc/testsuite/g++.dg/vect/simd-clone-3.cc.jj        2015-07-08 
18:05:48.203357688 +0200
+++ gcc/testsuite/g++.dg/vect/simd-clone-3.cc   2015-07-08 18:34:23.880149480 
+0200
@@ -0,0 +1,34 @@
+// { dg-require-effective-target vect_simd_clones }
+// { dg-additional-options "-fopenmp-simd -fno-inline" }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+// { dg-additional-sources "simd-clone-2.cc" }
+
+#include "simd-clone-2.h"
+
+#pragma omp declare simd notinbranch
+int
+S::f0 (int x)
+{
+  return x + s;
+}
+
+#pragma omp declare simd notinbranch uniform(this)
+int
+S::f1 (int x)
+{
+  return x + s;
+}
+
+#pragma omp declare simd notinbranch linear(this:sizeof(this)/sizeof(this))
+int
+S::f2 (int x)
+{
+  return x + this->S::s;
+}
+
+#pragma omp declare simd uniform(this) aligned(this:32) linear(x)
+int
+T::f3 (int x)
+{
+  return t[x];
+}
--- gcc/testsuite/g++.dg/vect/simd-clone-4.cc.jj        2015-07-08 
18:42:04.371685163 +0200
+++ gcc/testsuite/g++.dg/vect/simd-clone-4.cc   2015-07-08 18:42:23.137421732 
+0200
@@ -0,0 +1,55 @@
+// { dg-require-effective-target vect_simd_clones }
+// { dg-additional-options "-fopenmp-simd -fno-inline -DONE_FILE" }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+
+#include "../../gcc.dg/vect/tree-vect.h"
+
+#ifdef ONE_FILE
+#include "simd-clone-5.cc"
+#else
+#include "simd-clone-4.h"
+#endif
+
+T<0> b __attribute__((aligned (32)));
+
+void
+do_main ()
+{
+  int i, r = 0;
+  S<0> a[64];
+  for (i = 0; i < 64; i++)
+    {
+      a[i].s = i;
+      b.t[i] = i;
+    }
+  #pragma omp simd reduction(+:r)
+  for (i = 0; i < 64; i++)
+    r += a[16].f0 (i);
+  if (r != 64 * 63 / 2 + 64 * 16)
+    __builtin_abort ();
+  r = 0;
+  #pragma omp simd reduction(+:r)
+  for (i = 0; i < 64; i++)
+    r += a[32].f1 (i);
+  if (r != 64 * 63 / 2 + 64 * 32)
+    __builtin_abort ();
+  r = 0;
+  #pragma omp simd reduction(+:r)
+  for (i = 0; i < 64; i++)
+    r += a[i].f2 (i);
+  if (r != 64 * 63)
+    __builtin_abort ();
+  r = 0;
+  #pragma omp simd reduction(+:r)
+  for (i = 0; i < 64; i++)
+    r += b.f3 (i);
+  if (r != 64 * 63 / 2)
+    __builtin_abort ();
+}
+
+int
+main ()
+{
+  check_vect ();
+  do_main ();
+}
--- gcc/testsuite/g++.dg/vect/simd-clone-4.h.jj 2015-07-08 18:42:31.770300545 
+0200
+++ gcc/testsuite/g++.dg/vect/simd-clone-4.h    2015-07-08 18:42:45.939101645 
+0200
@@ -0,0 +1,19 @@
+template <int N>
+struct S
+{
+  int s;
+  #pragma omp declare simd notinbranch
+  int f0 (int x);
+  #pragma omp declare simd notinbranch uniform(this)
+  int f1 (int x);
+  #pragma omp declare simd notinbranch linear(this:sizeof(this)/sizeof(this))
+  int f2 (int x);
+};
+
+template <int N>
+struct T
+{
+  int t[64];
+  #pragma omp declare simd aligned(this:32) uniform(this) linear(x)
+  int f3 (int x);
+};
--- gcc/testsuite/g++.dg/vect/simd-clone-5.cc.jj        2015-07-08 
18:42:58.486925500 +0200
+++ gcc/testsuite/g++.dg/vect/simd-clone-5.cc   2015-07-08 18:46:28.469983704 
+0200
@@ -0,0 +1,41 @@
+// { dg-require-effective-target vect_simd_clones }
+// { dg-additional-options "-fopenmp-simd -fno-inline" }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+// { dg-additional-sources "simd-clone-4.cc" }
+
+#include "simd-clone-4.h"
+
+#pragma omp declare simd notinbranch
+template <int N>
+int
+S<N>::f0 (int x)
+{
+  return x + s;
+}
+
+#pragma omp declare simd notinbranch uniform(this)
+template <int N>
+int
+S<N>::f1 (int x)
+{
+  return x + s;
+}
+
+#pragma omp declare simd notinbranch linear(this:sizeof(this)/sizeof(this))
+template <int N>
+int
+S<N>::f2 (int x)
+{
+  return x + this->S::s;
+}
+
+#pragma omp declare simd uniform(this) aligned(this:32) linear(x)
+template <int N>
+int
+T<N>::f3 (int x)
+{
+  return t[x];
+}
+
+template struct S<0>;
+template struct T<0>;
--- gcc/testsuite/g++.dg/gomp/this-1.C.jj       2015-07-08 18:59:09.101366895 
+0200
+++ gcc/testsuite/g++.dg/gomp/this-1.C  2015-07-08 19:28:30.836733226 +0200
@@ -0,0 +1,68 @@
+// { dg-do compile }
+// { dg-options "-fopenmp" }
+
+struct S
+{
+  #pragma omp declare simd linear(this)                // { dg-error "is not 
an function argument" }
+  static void foo ();
+  void bar ();
+};
+
+void
+S::bar ()
+{
+  #pragma omp parallel firstprivate (this)     // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+    ;
+  #pragma omp parallel for lastprivate (this)  // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+  for (int i = 0; i < 10; i++)
+    ;
+  #pragma omp parallel shared (this)           // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+    ;
+  #pragma omp for linear (this)                        // { dg-error ".this. 
allowed in OpenMP only in .declare simd. clauses" }
+  for (int i = 0; i < 10; i++)
+    ;
+  #pragma omp task depend(inout: this)         // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+    ;
+  #pragma omp task depend(inout: this[0])      // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+    ;
+  #pragma omp parallel private (this)          // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+  {
+    #pragma omp single copyprivate (this)      // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+    ;
+  }
+}
+
+template <int N>
+struct T
+{
+  #pragma omp declare simd linear(this)                // { dg-error "is not 
an function argument" }
+  static void foo ();
+  void bar ();
+};
+
+template <int N>
+void
+T<N>::bar ()
+{
+  #pragma omp parallel firstprivate (this)     // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+    ;
+  #pragma omp parallel for lastprivate (this)  // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+  for (int i = 0; i < 10; i++)
+    ;
+  #pragma omp parallel shared (this)           // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+    ;
+  #pragma omp for linear (this)                        // { dg-error ".this. 
allowed in OpenMP only in .declare simd. clauses" }
+  for (int i = 0; i < 10; i++)
+    ;
+  #pragma omp task depend(inout: this)         // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+    ;
+  #pragma omp task depend(inout: this[0])      // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+    ;
+  #pragma omp parallel private (this)          // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+  {
+    #pragma omp single copyprivate (this)      // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+    ;
+  }
+}
+
+template struct T<0>;
--- gcc/testsuite/g++.dg/gomp/this-2.C.jj       2015-07-08 18:59:16.693260928 
+0200
+++ gcc/testsuite/g++.dg/gomp/this-2.C  2015-07-08 19:46:34.132605144 +0200
@@ -0,0 +1,42 @@
+// { dg-do compile }
+// { dg-options "-fopenmp" }
+
+struct S
+{
+  void bar (int);
+};
+
+void
+S::bar (int x)
+{
+  #pragma omp target map (this, x)             // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+    ;
+  #pragma omp target map (this[0], x)          // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+    ;
+  #pragma omp target update to (this, x)       // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+  #pragma omp target update to (this[0], x)    // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+  #pragma omp target update from (this, x)     // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+  #pragma omp target update from (this[1], x)  // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+}
+
+template <int N>
+struct T
+{
+  void bar (int);
+};
+
+template <int N>
+void
+T<N>::bar (int x)
+{
+  #pragma omp target map (this, x)             // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+    ;
+  #pragma omp target map (this[0], x)          // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+    ;
+  #pragma omp target update to (this, x)       // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+  #pragma omp target update to (this[0], x)    // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+  #pragma omp target update from (this, x)     // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+  #pragma omp target update from (this[1], x)  // { dg-error ".this. allowed 
in OpenMP only in .declare simd. clauses" }
+}
+
+template struct T<0>;


        Jakub

Reply via email to