gimplify.c (gimplify_scan_omp_clauses): Handle COMPONENT_REFs with base of reference...
authorJakub Jelinek <jakub@redhat.com>
Thu, 16 Jun 2016 19:03:05 +0000 (21:03 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 16 Jun 2016 19:03:05 +0000 (21:03 +0200)
* gimplify.c (gimplify_scan_omp_clauses): Handle COMPONENT_REFs
with base of reference to struct.

* parser.c (cp_parser_omp_var_list_no_open): Call
convert_from_reference before cp_parser_postfix_dot_deref_expression.
* semantics.c (finish_omp_clauses): Don't ICE when
processing_template_decl when checking for bitfields and unions.
Look through REFERENCE_REF_P as base of COMPONENT_REF.

* testsuite/libgomp.c++/target-20.C: New test.

From-SVN: r237538

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/cp/semantics.c
gcc/gimplify.c
libgomp/ChangeLog
libgomp/testsuite/libgomp.c++/target-20.C [new file with mode: 0644]

index a8e22ed32fe6189616b5e9e1614e201340174eb1..20e4ecdb4e046f352d669f3bd026d19141eabdd8 100644 (file)
@@ -1,3 +1,8 @@
+2016-06-16  Jakub Jelinek  <jakub@redhat.com>
+
+       * gimplify.c (gimplify_scan_omp_clauses): Handle COMPONENT_REFs
+       with base of reference to struct.
+
 2016-06-16  Uros Bizjak  <ubizjak@gmail.com>
 
        * doc/invoke.texi (x86 Options): Document -m80387 and -mhard-float.
index d62ab39d43836d4d6f9d89774e7133797aa3697f..5ad3354d69ca80ed4479ec693dacbf6fba8f2584 100644 (file)
@@ -1,3 +1,11 @@
+2016-06-16  Jakub Jelinek  <jakub@redhat.com>
+
+       * parser.c (cp_parser_omp_var_list_no_open): Call
+       convert_from_reference before cp_parser_postfix_dot_deref_expression.
+       * semantics.c (finish_omp_clauses): Don't ICE when
+       processing_template_decl when checking for bitfields and unions.
+       Look through REFERENCE_REF_P as base of COMPONENT_REF.
+
 2016-06-15  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * decl.c (wrapup_globals_for_namespace): Use DECL_SOURCE_LOCATION and
index a9c636b7f41fb9c4fa3a9f79f7987b7449659458..0846f0c04ea1f5c1ccdaa460eb4e27a0077d242a 100644 (file)
@@ -30001,6 +30001,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
                    = cp_lexer_peek_token (parser->lexer)->location;
                  cp_id_kind idk = CP_ID_KIND_NONE;
                  cp_lexer_consume_token (parser->lexer);
+                 decl = convert_from_reference (decl);
                  decl
                    = cp_parser_postfix_dot_deref_expression (parser, CPP_DOT,
                                                              decl, false,
index 9b0cff8c3107c70857f92bfd9e6a4b11e8a8b54b..4cc5d2316fb5e7f1a53d21c4f08cd2276dc751d7 100644 (file)
@@ -6664,7 +6664,8 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
            {
              if (type_dependent_expression_p (t))
                break;
-             if (DECL_BIT_FIELD (TREE_OPERAND (t, 1)))
+             if (TREE_CODE (TREE_OPERAND (t, 1)) == FIELD_DECL
+                 && DECL_BIT_FIELD (TREE_OPERAND (t, 1)))
                {
                  error_at (OMP_CLAUSE_LOCATION (c),
                            "bit-field %qE in %qs clause",
@@ -6680,8 +6681,9 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
                }
              while (TREE_CODE (t) == COMPONENT_REF)
                {
-                 if (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0)))
-                     == UNION_TYPE)
+                 if (TREE_TYPE (TREE_OPERAND (t, 0))
+                     && (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0)))
+                         == UNION_TYPE))
                    {
                      error_at (OMP_CLAUSE_LOCATION (c),
                                "%qE is a member of a union", t);
@@ -6692,6 +6694,8 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
                }
              if (remove)
                break;
+             if (REFERENCE_REF_P (t))
+               t = TREE_OPERAND (t, 0);
              if (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
                {
                  if (bitmap_bit_p (&map_field_head, DECL_UID (t)))
index ae8b4fcce3cf3d74214be7ca2eaee4670b95e346..47c4d253e41ddb49d21d7c19c7f2b9201866bf9e 100644 (file)
@@ -6983,6 +6983,11 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
                {
                  while (TREE_CODE (decl) == COMPONENT_REF)
                    decl = TREE_OPERAND (decl, 0);
+                 if (TREE_CODE (decl) == INDIRECT_REF
+                     && DECL_P (TREE_OPERAND (decl, 0))
+                     && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
+                         == REFERENCE_TYPE))
+                   decl = TREE_OPERAND (decl, 0);
                }
              if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue, fb_lvalue)
                  == GS_ERROR)
@@ -6998,9 +7003,11 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
                      break;
                    }
 
-                 if (TYPE_SIZE_UNIT (TREE_TYPE (decl)) == NULL
-                     || (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (decl)))
-                         != INTEGER_CST))
+                 tree stype = TREE_TYPE (decl);
+                 if (TREE_CODE (stype) == REFERENCE_TYPE)
+                   stype = TREE_TYPE (stype);
+                 if (TYPE_SIZE_UNIT (stype) == NULL
+                     || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
                    {
                      error_at (OMP_CLAUSE_LOCATION (c),
                                "mapping field %qE of variable length "
@@ -7040,6 +7047,14 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
                  base = get_inner_reference (base, &bitsize, &bitpos, &offset,
                                              &mode, &unsignedp, &reversep,
                                              &volatilep, false);
+                 tree orig_base = base;
+                 if ((TREE_CODE (base) == INDIRECT_REF
+                      || (TREE_CODE (base) == MEM_REF
+                          && integer_zerop (TREE_OPERAND (base, 1))))
+                     && DECL_P (TREE_OPERAND (base, 0))
+                     && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
+                         == REFERENCE_TYPE))
+                   base = TREE_OPERAND (base, 0);
                  gcc_assert (base == decl
                              && (offset == NULL_TREE
                                  || TREE_CODE (offset) == INTEGER_CST));
@@ -7053,7 +7068,10 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
                      tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c),
                                                 OMP_CLAUSE_MAP);
                      OMP_CLAUSE_SET_MAP_KIND (l, GOMP_MAP_STRUCT);
-                     OMP_CLAUSE_DECL (l) = decl;
+                     if (orig_base != base)
+                       OMP_CLAUSE_DECL (l) = unshare_expr (orig_base);
+                     else
+                       OMP_CLAUSE_DECL (l) = decl;
                      OMP_CLAUSE_SIZE (l) = size_int (1);
                      if (struct_map_to_clause == NULL)
                        struct_map_to_clause = new hash_map<tree, tree>;
@@ -7095,6 +7113,18 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
                          *list_p = l;
                          list_p = &OMP_CLAUSE_CHAIN (l);
                        }
+                     if (orig_base != base && code == OMP_TARGET)
+                       {
+                         tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
+                                                     OMP_CLAUSE_MAP);
+                         enum gomp_map_kind mkind
+                           = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
+                         OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
+                         OMP_CLAUSE_DECL (c2) = decl;
+                         OMP_CLAUSE_SIZE (c2) = size_zero_node;
+                         OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
+                         OMP_CLAUSE_CHAIN (l) = c2;
+                       }
                      flags = GOVD_MAP | GOVD_EXPLICIT;
                      if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) || ptr)
                        flags |= GOVD_SEEN;
@@ -7113,8 +7143,12 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
                        o1 = 0;
                      if (bitpos)
                        o1 = o1 + bitpos / BITS_PER_UNIT;
-                     for (sc = &OMP_CLAUSE_CHAIN (*osc);
-                          *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc))
+                     sc = &OMP_CLAUSE_CHAIN (*osc);
+                     if (*sc != c
+                         && (OMP_CLAUSE_MAP_KIND (*sc)
+                             == GOMP_MAP_FIRSTPRIVATE_REFERENCE)) 
+                       sc = &OMP_CLAUSE_CHAIN (*sc);
+                     for (; *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc))
                        if (ptr && sc == prev_list_p)
                          break;
                        else if (TREE_CODE (OMP_CLAUSE_DECL (*sc))
@@ -7150,6 +7184,15 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
                                                        &mode, &unsignedp,
                                                        &reversep, &volatilep,
                                                        false);
+                           if ((TREE_CODE (base) == INDIRECT_REF
+                                || (TREE_CODE (base) == MEM_REF
+                                    && integer_zerop (TREE_OPERAND (base,
+                                                                    1))))
+                               && DECL_P (TREE_OPERAND (base, 0))
+                               && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base,
+                                                                       0)))
+                                   == REFERENCE_TYPE))
+                             base = TREE_OPERAND (base, 0);
                            if (base != decl)
                              break;
                            if (scp)
index cf551f49384f640149e2a0aa003345d823adc134..586657bb1309979733db94860afcfea71634dd85 100644 (file)
@@ -1,3 +1,7 @@
+2016-06-16  Jakub Jelinek  <jakub@redhat.com>
+
+       * testsuite/libgomp.c++/target-20.C: New test.
+
 2016-06-10  Thomas Schwinge  <thomas@codesourcery.com>
            Cesar Philippidis  <cesar@codesourcery.com>
 
diff --git a/libgomp/testsuite/libgomp.c++/target-20.C b/libgomp/testsuite/libgomp.c++/target-20.C
new file mode 100644 (file)
index 0000000..a722ec0
--- /dev/null
@@ -0,0 +1,80 @@
+extern "C" void abort ();
+struct S { int a, b, c, d; };
+
+void
+foo (S &s)
+{
+  int err;
+  #pragma omp target map (s.b, s.d) map (from: err)
+  {
+    err = s.b != 21 || s.d != 24;
+    s.b++; s.d++;
+  }
+  if (err || s.b != 22 || s.d != 25)
+    abort ();
+  #pragma omp target data map (s.b, s.d)
+  {
+    #pragma omp target map (alloc: s.b, s.d) map (from: err)
+    {
+      err = s.b != 22 || s.d != 25;
+      s.b++; s.d++;
+    }
+  }
+  if (err || s.b != 23 || s.d != 26)
+    abort ();
+  #pragma omp target data map (s)
+  {
+    #pragma omp target map (alloc: s.b, s.d) map (from: err)
+    {
+      err = s.b != 23 || s.d != 26;
+      s.b++; s.d++;
+    }
+  }
+  if (err || s.b != 24 || s.d != 27)
+    abort ();
+}
+
+template <typename T, typename U>
+void
+bar (S &s, T &t, U u)
+{
+  int err;
+  #pragma omp target map (s.b, s.d, t.b, t.d, u.b, u.d) map (from: err)
+  {
+    err = s.b != 21 || s.d != 24 || t.b != 73 || t.d != 82 || u.b != 31 || u.d != 37;
+    s.b++; s.d++; t.b++; t.d++; u.b++; u.d++;
+  }
+  if (err || s.b != 22 || s.d != 25 || t.b != 74 || t.d != 83 || u.b != 32 || u.d != 38)
+    abort ();
+  #pragma omp target data map (s.b, s.d, t.b, t.d, u.b, u.d)
+  {
+    #pragma omp target map (alloc: s.b, s.d, t.b, t.d, u.b, u.d) map (from: err)
+    {
+      err = s.b != 22 || s.d != 25 || t.b != 74 || t.d != 83 || u.b != 32 || u.d != 38;
+      s.b++; s.d++; t.b++; t.d++; u.b++; u.d++;
+    }
+  }
+  if (err || s.b != 23 || s.d != 26 || t.b != 75 || t.d != 84 || u.b != 33 || u.d != 39)
+    abort ();
+  #pragma omp target data map (s, t, u)
+  {
+    #pragma omp target map (alloc: s.b, s.d, t.b, t.d, u.b, u.d) map (from: err)
+    {
+      err = s.b != 23 || s.d != 26 || t.b != 75 || t.d != 84 || u.b != 33 || u.d != 39;
+      s.b++; s.d++; t.b++; t.d++; u.b++; u.d++;
+    }
+  }
+  if (err || s.b != 24 || s.d != 27 || t.b != 76 || t.d != 85 || u.b != 34 || u.d != 40)
+    abort ();
+}
+
+int
+main ()
+{
+  S s = { 1, 21, 2, 24 };
+  foo (s);
+  S s2 = { 3, 21, 4, 24 };
+  S t = { 5, 73, 6, 82 };
+  S u = { 7, 31, 8, 37 };
+  bar <S, S &> (s2, t, u);
+}