Hi!

This patch improves cp_omp_mappable_type, fixes reference to pointer based
array sections, and diagnoses if map/to/from clauses don't have decls
or array sections with mappable type.

2013-06-14  Jakub Jelinek  <ja...@redhat.com>

        * decl2.c (cp_omp_mappable_type): No longer static.  Handle array
        types and recurse for FIELD_DECL types.
        * semantics.c (handle_omp_array_sections_1): Call
        convert_from_reference before testing for pointer_based_p.
        (finish_omp_clauses): Complain if OMP_CLAUSE_{MAP,TO,FROM}
        decls or array sections don't have cp_omp_mappable_type.
        * cp-tree.h (cp_omp_mappable_type): New prototype.

--- gcc/cp/decl2.c.jj   2013-05-29 10:05:42.000000000 +0200
+++ gcc/cp/decl2.c      2013-06-14 12:09:18.284393933 +0200
@@ -1334,12 +1334,15 @@ cp_check_const_attributes (tree attribut
 }
 
 /* Return true if TYPE is an OpenMP mappable type.  */
-static bool
+bool
 cp_omp_mappable_type (tree type)
 {
   /* Mappable type has to be complete.  */
   if (type == error_mark_node || !COMPLETE_TYPE_P (type))
     return false;
+  /* Arrays have mappable type if the elements have mappable type.  */
+  while (TREE_CODE (type) == ARRAY_TYPE)
+    type = TREE_TYPE (type);
   /* A mappable type cannot contain virtual members.  */
   if (CLASS_TYPE_P (type) && CLASSTYPE_VTABLES (type))
     return false;
@@ -1350,6 +1353,10 @@ cp_omp_mappable_type (tree type)
       for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
        if (TREE_CODE (field) == VAR_DECL)
          return false;
+       /* All fields must have mappable types.  */
+       else if (TREE_CODE (field) == FIELD_DECL
+                && !cp_omp_mappable_type (TREE_TYPE (field)))
+         return false;
     }
   return true;
 }
--- gcc/cp/semantics.c.jj       2013-06-12 15:00:11.000000000 +0200
+++ gcc/cp/semantics.c  2013-06-14 12:09:18.287394537 +0200
@@ -4122,11 +4122,11 @@ handle_omp_array_sections_1 (tree c, tre
                    omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
          return error_mark_node;
        }
+      t = convert_from_reference (t);
       if (!processing_template_decl
          && POINTER_TYPE_P (TREE_TYPE (t))
          && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
        pointer_based_p = true;
-      t = convert_from_reference (t);
       return t;
     }
 
@@ -4921,6 +4921,18 @@ finish_omp_clauses (tree clauses)
            {
              if (handle_omp_array_sections (c))
                remove = true;
+             else
+               {
+                 t = OMP_CLAUSE_DECL (c);
+                 if (!cp_omp_mappable_type (TREE_TYPE (t)))
+                   {
+                     error_at (OMP_CLAUSE_LOCATION (c),
+                               "array section does not have mappable type "
+                               "in %qs clause",
+                               omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+                     remove = true;
+                   }
+               }
              break;
            }
          if (t == error_mark_node)
@@ -4947,6 +4959,16 @@ finish_omp_clauses (tree clauses)
                   && TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE
                   && !cxx_mark_addressable (t))
            remove = true;
+         else if (!cp_omp_mappable_type ((TREE_CODE (TREE_TYPE (t))
+                                          == REFERENCE_TYPE)
+                                         ? TREE_TYPE (TREE_TYPE (t))
+                                         : TREE_TYPE (t)))
+           {
+             error_at (OMP_CLAUSE_LOCATION (c),
+                       "%qD does not have a mappable type in %qs clause", t,
+                       omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+             remove = true;
+           }
          else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
            break;
          else if (bitmap_bit_p (&generic_head, DECL_UID (t)))
--- gcc/cp/cp-tree.h.jj 2013-05-29 10:05:42.000000000 +0200
+++ gcc/cp/cp-tree.h    2013-06-13 12:26:37.480571572 +0200
@@ -5297,6 +5296,7 @@ extern void note_vague_linkage_fn         (tree
 extern tree build_artificial_parm              (tree, tree);
 extern bool possibly_inlined_p                 (tree);
 extern int parm_index                           (tree);
+extern bool cp_omp_mappable_type               (tree);
 
 /* in error.c */
 extern void init_error                         (void);

        Jakub

Reply via email to