@@ -1254,6 +1254,50 @@ extern const char *c_omp_map_clause_name (tree, bool);
extern void c_omp_adjust_map_clauses (tree, bool);
extern tree c_omp_decompose_attachable_address (tree t, tree *virtbase);
+class c_omp_address_inspector
+{
+ tree clause;
+ tree orig;
+ tree deref_toplevel;
+ tree outer_virtual_base;
+ tree root_term;
+ bool component_access;
+ bool indirections;
+ int map_supported;
+
+protected:
+ virtual bool reference_ref_p (tree) { return false; }
+ virtual bool processing_template_decl_p () { return false; }
+ virtual bool mappable_type (tree t);
+ virtual void emit_unmappable_type_notes (tree) { }
+
+public:
+ c_omp_address_inspector (tree c, tree t)
+ : clause (c), orig (t), deref_toplevel (NULL_TREE),
+ outer_virtual_base (NULL_TREE), root_term (NULL_TREE),
+ component_access (false), indirections (false), map_supported (-1)
+ { }
+
+ ~c_omp_address_inspector () {}
+
+ virtual void init ();
+
+ tree analyze_components (bool);
+
+ tree get_deref_toplevel () { return deref_toplevel; }
+ tree get_outer_virtual_base () { return outer_virtual_base; }
+ tree get_root_term () { gcc_assert (root_term); return root_term; }
+ bool component_access_p () { return component_access; }
+
+ bool indir_component_ref_p ()
+ {
+ gcc_assert (!component_access || root_term != NULL_TREE);
+ return component_access && indirections;
+ }
+
+ bool map_supported_p ();
+};
+
enum c_omp_directive_kind {
C_OMP_DIR_STANDALONE,
C_OMP_DIR_CONSTRUCT,
@@ -3113,6 +3113,156 @@ c_omp_adjust_map_clauses (tree clauses, bool is_target)
}
}
+/* This could just be done in the constructor, but we need to call the
+ subclass's version of reference_ref_p, etc. */
+
+void
+c_omp_address_inspector::init ()
+{
+ tree t = orig;
+
+ gcc_assert (TREE_CODE (t) != ARRAY_REF);
+
+ /* We may have a reference-typed component access at the outermost level
+ that has had convert_from_reference called on it. Look through that
+ access. */
+ if (reference_ref_p (t)
+ && TREE_CODE (TREE_OPERAND (t, 0)) == COMPONENT_REF)
+ {
+ t = TREE_OPERAND (t, 0);
+ deref_toplevel = t;
+ }
+ else
+ deref_toplevel = t;
+
+ /* Strip off expression nodes that may enclose a COMPONENT_REF. Look through
+ references, but not indirections through pointers. */
+ while (1)
+ {
+ if (TREE_CODE (t) == COMPOUND_EXPR)
+ {
+ t = TREE_OPERAND (t, 1);
+ STRIP_NOPS (t);
+ }
+ else if (TREE_CODE (t) == POINTER_PLUS_EXPR
+ || TREE_CODE (t) == SAVE_EXPR)
+ t = TREE_OPERAND (t, 0);
+ else if (reference_ref_p (t))
+ t = TREE_OPERAND (t, 0);
+ else
+ break;
+ }
+
+ outer_virtual_base = t;
+
+ if (TREE_CODE (t) == COMPONENT_REF)
+ component_access = true;
+}
+
+tree
+c_omp_address_inspector::analyze_components (bool checking)
+{
+ if (root_term)
+ return root_term;
+
+ gcc_assert (TREE_CODE (outer_virtual_base) == COMPONENT_REF);
+
+ tree t = outer_virtual_base;
+
+ if (checking
+ && TREE_CODE (TREE_OPERAND (t, 1)) == FIELD_DECL
+ && DECL_BIT_FIELD (TREE_OPERAND (t, 1)))
+ {
+ error_at (OMP_CLAUSE_LOCATION (clause),
+ "bit-field %qE in %qs clause",
+ t, omp_clause_code_name[OMP_CLAUSE_CODE (clause)]);
+ return error_mark_node;
+ }
+ else if (checking
+ && !processing_template_decl_p ()
+ && !mappable_type (TREE_TYPE (t)))
+ {
+ error_at (OMP_CLAUSE_LOCATION (clause),
+ "%qE does not have a mappable type in %qs clause",
+ t, omp_clause_code_name[OMP_CLAUSE_CODE (clause)]);
+ emit_unmappable_type_notes (TREE_TYPE (t));
+ return error_mark_node;
+ }
+ else if (checking && TREE_TYPE (t) && TYPE_ATOMIC (TREE_TYPE (t)))
+ {
+ error_at (OMP_CLAUSE_LOCATION (clause),
+ "%<_Atomic%> %qE in %qs clause", t,
+ omp_clause_code_name[OMP_CLAUSE_CODE (clause)]);
+ return error_mark_node;
+ }
+
+ while (TREE_CODE (t) == COMPONENT_REF)
+ {
+ if (checking
+ && TREE_TYPE (TREE_OPERAND (t, 0))
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == UNION_TYPE)
+ {
+ error_at (OMP_CLAUSE_LOCATION (clause),
+ "%qE is a member of a union", t);
+ return error_mark_node;
+ }
+ t = TREE_OPERAND (t, 0);
+ while (TREE_CODE (t) == MEM_REF
+ || TREE_CODE (t) == INDIRECT_REF
+ || TREE_CODE (t) == ARRAY_REF)
+ {
+ if (TREE_CODE (t) == MEM_REF
+ || TREE_CODE (t) == INDIRECT_REF)
+ indirections = true;
+ t = TREE_OPERAND (t, 0);
+ STRIP_NOPS (t);
+ if (TREE_CODE (t) == POINTER_PLUS_EXPR)
+ t = TREE_OPERAND (t, 0);
+ }
+ }
+
+ root_term = t;
+
+ return t;
+}
+
+bool
+c_omp_address_inspector::map_supported_p ()
+{
+ /* If we've already decided if the mapped address is supported, return
+ that. */
+ if (map_supported != -1)
+ return map_supported;
+
+ /* Get the innermost point recorded so far. */
+ tree t = root_term ? root_term : outer_virtual_base;
+
+ STRIP_NOPS (t);
+
+ while (TREE_CODE (t) == INDIRECT_REF
+ || TREE_CODE (t) == MEM_REF
+ || TREE_CODE (t) == ARRAY_REF
+ || TREE_CODE (t) == COMPONENT_REF
+ || TREE_CODE (t) == COMPOUND_EXPR
+ || TREE_CODE (t) == SAVE_EXPR
+ || TREE_CODE (t) == POINTER_PLUS_EXPR
+ || TREE_CODE (t) == NON_LVALUE_EXPR)
+ if (TREE_CODE (t) == COMPOUND_EXPR)
+ t = TREE_OPERAND (t, 1);
+ else
+ t = TREE_OPERAND (t, 0);
+
+ map_supported = DECL_P (t);
+
+ return map_supported;
+}
+
+bool
+c_omp_address_inspector::mappable_type (tree t)
+{
+ return lang_hooks.types.omp_mappable_type (t);
+}
+
tree
c_omp_decompose_attachable_address (tree t, tree *virtbase)
{
@@ -13212,6 +13212,8 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
{
if (error_operand_p (t))
return error_mark_node;
+ c_omp_address_inspector t_insp (c, t);
+ t_insp.init ();
ret = t;
if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY
&& OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
@@ -13221,59 +13223,15 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
t, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
return error_mark_node;
}
- while (TREE_CODE (t) == INDIRECT_REF)
- {
- t = TREE_OPERAND (t, 0);
- STRIP_NOPS (t);
- if (TREE_CODE (t) == POINTER_PLUS_EXPR)
- t = TREE_OPERAND (t, 0);
- }
- while (TREE_CODE (t) == COMPOUND_EXPR)
- {
- t = TREE_OPERAND (t, 1);
- STRIP_NOPS (t);
- }
- if (TREE_CODE (t) == COMPONENT_REF
+ if (t_insp.component_access_p ()
&& (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
|| OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TO
|| OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FROM))
- {
- if (DECL_BIT_FIELD (TREE_OPERAND (t, 1)))
- {
- error_at (OMP_CLAUSE_LOCATION (c),
- "bit-field %qE in %qs clause",
- t, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
- return error_mark_node;
- }
- while (TREE_CODE (t) == COMPONENT_REF)
- {
- if (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == UNION_TYPE)
- {
- error_at (OMP_CLAUSE_LOCATION (c),
- "%qE is a member of a union", t);
- return error_mark_node;
- }
- t = TREE_OPERAND (t, 0);
- while (TREE_CODE (t) == MEM_REF
- || TREE_CODE (t) == INDIRECT_REF
- || TREE_CODE (t) == ARRAY_REF)
- {
- t = TREE_OPERAND (t, 0);
- STRIP_NOPS (t);
- if (TREE_CODE (t) == POINTER_PLUS_EXPR)
- t = TREE_OPERAND (t, 0);
- }
- if (ort == C_ORT_ACC && TREE_CODE (t) == MEM_REF)
- {
- if (maybe_ne (mem_ref_offset (t), 0))
- error_at (OMP_CLAUSE_LOCATION (c),
- "cannot dereference %qE in %qs clause", t,
- omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
- else
- t = TREE_OPERAND (t, 0);
- }
- }
- }
+ t = t_insp.analyze_components (true);
+ else
+ t = t_insp.get_outer_virtual_base ();
+ if (t == error_mark_node)
+ return error_mark_node;
if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
{
if (DECL_P (t))
@@ -14920,24 +14878,16 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
}
while (TREE_CODE (t) == ARRAY_REF)
t = TREE_OPERAND (t, 0);
- if (TREE_CODE (t) == COMPONENT_REF
- && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
+
+ c_omp_address_inspector t_insp (c, t);
+ t_insp.init ();
+
+ tree ovb = t_insp.get_outer_virtual_base ();
+
+ if (TREE_CODE (ovb) == COMPONENT_REF
+ && TREE_CODE (TREE_TYPE (ovb)) == ARRAY_TYPE)
{
- do
- {
- t = TREE_OPERAND (t, 0);
- if (TREE_CODE (t) == MEM_REF
- || TREE_CODE (t) == INDIRECT_REF
- || TREE_CODE (t) == ARRAY_REF)
- {
- t = TREE_OPERAND (t, 0);
- STRIP_NOPS (t);
- if (TREE_CODE (t) == POINTER_PLUS_EXPR)
- t = TREE_OPERAND (t, 0);
- }
- }
- while (TREE_CODE (t) == COMPONENT_REF
- || TREE_CODE (t) == ARRAY_REF);
+ t = t_insp.analyze_components (false);
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
&& OMP_CLAUSE_MAP_IMPLICIT (c)
@@ -15005,96 +14955,35 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
bias) to zero here, so it is not set erroneously to the pointer
size later on in gimplify.cc. */
OMP_CLAUSE_SIZE (c) = size_zero_node;
- while (TREE_CODE (t) == INDIRECT_REF
- || TREE_CODE (t) == ARRAY_REF)
- {
- t = TREE_OPERAND (t, 0);
- STRIP_NOPS (t);
- if (TREE_CODE (t) == POINTER_PLUS_EXPR)
- t = TREE_OPERAND (t, 0);
- }
- while (TREE_CODE (t) == COMPOUND_EXPR)
- {
- t = TREE_OPERAND (t, 1);
- STRIP_NOPS (t);
- }
- indir_component_ref_p = false;
- if (TREE_CODE (t) == COMPONENT_REF
- && (TREE_CODE (TREE_OPERAND (t, 0)) == MEM_REF
- || TREE_CODE (TREE_OPERAND (t, 0)) == INDIRECT_REF
- || TREE_CODE (TREE_OPERAND (t, 0)) == ARRAY_REF))
- {
- t = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
- indir_component_ref_p = true;
- STRIP_NOPS (t);
- if (TREE_CODE (t) == POINTER_PLUS_EXPR)
- t = TREE_OPERAND (t, 0);
- }
- if (TREE_CODE (t) == COMPONENT_REF
- && OMP_CLAUSE_CODE (c) != OMP_CLAUSE__CACHE_)
- {
- if (DECL_BIT_FIELD (TREE_OPERAND (t, 1)))
- {
- error_at (OMP_CLAUSE_LOCATION (c),
- "bit-field %qE in %qs clause",
- t, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
- remove = true;
- }
- else if (!lang_hooks.types.omp_mappable_type (TREE_TYPE (t)))
- {
- error_at (OMP_CLAUSE_LOCATION (c),
- "%qE does not have a mappable type in %qs clause",
- t, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
- remove = true;
- }
- else if (TYPE_ATOMIC (TREE_TYPE (t)))
- {
- error_at (OMP_CLAUSE_LOCATION (c),
- "%<_Atomic%> %qE in %qs clause", t,
- omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
- remove = true;
- }
- while (TREE_CODE (t) == COMPONENT_REF)
- {
- if (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0)))
- == UNION_TYPE)
- {
- error_at (OMP_CLAUSE_LOCATION (c),
- "%qE is a member of a union", t);
- remove = true;
- break;
- }
- t = TREE_OPERAND (t, 0);
- if (TREE_CODE (t) == MEM_REF)
- {
- if (maybe_ne (mem_ref_offset (t), 0))
- error_at (OMP_CLAUSE_LOCATION (c),
- "cannot dereference %qE in %qs clause", t,
- omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
- else
- t = TREE_OPERAND (t, 0);
- }
- while (TREE_CODE (t) == MEM_REF
- || TREE_CODE (t) == INDIRECT_REF
- || TREE_CODE (t) == ARRAY_REF)
- {
- t = TREE_OPERAND (t, 0);
- STRIP_NOPS (t);
- if (TREE_CODE (t) == POINTER_PLUS_EXPR)
- t = TREE_OPERAND (t, 0);
- }
- }
- if (remove)
+ {
+ c_omp_address_inspector t_insp (c, t);
+ t_insp.init ();
+
+ if (t_insp.component_access_p ()
+ && OMP_CLAUSE_CODE (c) != OMP_CLAUSE__CACHE_)
+ t = t_insp.analyze_components (true);
+ else
+ t = t_insp.get_outer_virtual_base ();
+
+ if (t == error_mark_node)
+ {
+ remove = true;
break;
- if (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
- {
- if (bitmap_bit_p (&map_field_head, DECL_UID (t))
- || (ort != C_ORT_ACC
- && bitmap_bit_p (&map_head, DECL_UID (t))))
- break;
- }
- }
+ }
+
+ indir_component_ref_p = t_insp.indir_component_ref_p ();
+
+ if (t_insp.component_access_p ()
+ && (VAR_P (t) || TREE_CODE (t) == PARM_DECL))
+ {
+ if (bitmap_bit_p (&map_field_head, DECL_UID (t))
+ || (ort != C_ORT_ACC
+ && bitmap_bit_p (&map_head, DECL_UID (t))))
+ break;
+ }
+ }
+
if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
{
error_at (OMP_CLAUSE_LOCATION (c),
@@ -5026,6 +5026,39 @@ omp_privatize_field (tree t, bool shared)
return v;
}
+/* C++ specialisation of the c_omp_address_inspector class. */
+
+class cp_omp_address_inspector : public c_omp_address_inspector
+{
+protected:
+ bool reference_ref_p (tree t)
+ {
+ return REFERENCE_REF_P (t);
+ }
+
+ bool processing_template_decl_p ()
+ {
+ return processing_template_decl;
+ }
+
+ bool mappable_type (tree t)
+ {
+ return cp_omp_mappable_type (t);
+ }
+
+ void emit_unmappable_type_notes (tree t)
+ {
+ cp_omp_emit_unmappable_type_notes (t);
+ }
+
+public:
+ cp_omp_address_inspector (tree c, tree t) : c_omp_address_inspector (c, t)
+ { }
+
+ ~cp_omp_address_inspector ()
+ { }
+};
+
/* Helper function for handle_omp_array_sections. Called recursively
to handle multiple array-section-subscripts. C is the clause,
T current expression (initially OMP_CLAUSE_DECL), which is either
@@ -5056,59 +5089,18 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
{
if (error_operand_p (t))
return error_mark_node;
- if (REFERENCE_REF_P (t)
- && TREE_CODE (TREE_OPERAND (t, 0)) == COMPONENT_REF)
- t = TREE_OPERAND (t, 0);
- ret = t;
- while (TREE_CODE (t) == INDIRECT_REF)
- {
- t = TREE_OPERAND (t, 0);
- STRIP_NOPS (t);
- if (TREE_CODE (t) == POINTER_PLUS_EXPR)
- t = TREE_OPERAND (t, 0);
- }
- while (TREE_CODE (t) == COMPOUND_EXPR)
- {
- t = TREE_OPERAND (t, 1);
- STRIP_NOPS (t);
- }
- if (TREE_CODE (t) == COMPONENT_REF
+ cp_omp_address_inspector t_insp (c, t);
+ t_insp.init ();
+ if (t_insp.component_access_p ()
&& (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
|| OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TO
- || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FROM)
- && !type_dependent_expression_p (t))
- {
- 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",
- t, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
- return error_mark_node;
- }
- while (TREE_CODE (t) == COMPONENT_REF)
- {
- 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);
- return error_mark_node;
- }
- t = TREE_OPERAND (t, 0);
- while (TREE_CODE (t) == MEM_REF
- || TREE_CODE (t) == INDIRECT_REF
- || TREE_CODE (t) == ARRAY_REF)
- {
- t = TREE_OPERAND (t, 0);
- STRIP_NOPS (t);
- if (TREE_CODE (t) == POINTER_PLUS_EXPR)
- t = TREE_OPERAND (t, 0);
- }
- }
- if (REFERENCE_REF_P (t))
- t = TREE_OPERAND (t, 0);
- }
+ || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FROM))
+ t = t_insp.analyze_components (true);
+ else
+ t = t_insp.get_outer_virtual_base ();
+ if (t == error_mark_node)
+ return error_mark_node;
+ ret = t_insp.get_deref_toplevel ();
if (TREE_CODE (t) == FIELD_DECL)
ret = finish_non_static_data_member (t, NULL_TREE, NULL_TREE);
else if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
@@ -7937,28 +7929,15 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
}
while (TREE_CODE (t) == ARRAY_REF)
t = TREE_OPERAND (t, 0);
- if (TREE_CODE (t) == COMPONENT_REF
- && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
+
+ cp_omp_address_inspector t_insp (c, t);
+ t_insp.init ();
+ tree ovb = t_insp.get_outer_virtual_base ();
+
+ if (TREE_CODE (ovb) == COMPONENT_REF
+ && TREE_CODE (TREE_TYPE (ovb)) == ARRAY_TYPE)
{
- do
- {
- t = TREE_OPERAND (t, 0);
- if (REFERENCE_REF_P (t))
- t = TREE_OPERAND (t, 0);
- if (TREE_CODE (t) == MEM_REF
- || TREE_CODE (t) == INDIRECT_REF
- || TREE_CODE (t) == ARRAY_REF)
- {
- t = TREE_OPERAND (t, 0);
- STRIP_NOPS (t);
- if (TREE_CODE (t) == POINTER_PLUS_EXPR)
- t = TREE_OPERAND (t, 0);
- if (REFERENCE_REF_P (t))
- t = TREE_OPERAND (t, 0);
- }
- }
- while (TREE_CODE (t) == COMPONENT_REF
- || TREE_CODE (t) == ARRAY_REF);
+ t = t_insp.analyze_components (false);
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
&& OMP_CLAUSE_MAP_IMPLICIT (c)
@@ -8026,106 +8005,38 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
bias) to zero here, so it is not set erroneously to the pointer
size later on in gimplify.cc. */
OMP_CLAUSE_SIZE (c) = size_zero_node;
- if (REFERENCE_REF_P (t)
- && TREE_CODE (TREE_OPERAND (t, 0)) == COMPONENT_REF)
- {
- t = TREE_OPERAND (t, 0);
- if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
- && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH)
- OMP_CLAUSE_DECL (c) = t;
- }
- while (TREE_CODE (t) == INDIRECT_REF
- || TREE_CODE (t) == ARRAY_REF)
- {
- t = TREE_OPERAND (t, 0);
- STRIP_NOPS (t);
- if (TREE_CODE (t) == POINTER_PLUS_EXPR)
- t = TREE_OPERAND (t, 0);
- }
- while (TREE_CODE (t) == COMPOUND_EXPR)
- {
- t = TREE_OPERAND (t, 1);
- STRIP_NOPS (t);
- }
- indir_component_ref_p = false;
- if (TREE_CODE (t) == COMPONENT_REF
- && (TREE_CODE (TREE_OPERAND (t, 0)) == INDIRECT_REF
- || TREE_CODE (TREE_OPERAND (t, 0)) == ARRAY_REF))
- {
- t = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
- indir_component_ref_p = true;
- if (REFERENCE_REF_P (t))
- t = TREE_OPERAND (t, 0);
- STRIP_NOPS (t);
- if (TREE_CODE (t) == POINTER_PLUS_EXPR)
- t = TREE_OPERAND (t, 0);
- }
- if (TREE_CODE (t) == COMPONENT_REF
- && OMP_CLAUSE_CODE (c) != OMP_CLAUSE__CACHE_)
- {
- if (type_dependent_expression_p (t))
+
+ {
+ cp_omp_address_inspector t_insp (c, t);
+ t_insp.init ();
+
+ if (t_insp.component_access_p ()
+ && OMP_CLAUSE_CODE (c) != OMP_CLAUSE__CACHE_)
+ t = t_insp.analyze_components (true);
+ else
+ t = t_insp.get_outer_virtual_base ();
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
+ && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH)
+ OMP_CLAUSE_DECL (c) = t_insp.get_deref_toplevel ();
+ if (type_dependent_expression_p (t_insp.get_deref_toplevel ()))
+ break;
+ if (t == error_mark_node)
+ {
+ remove = true;
break;
- 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",
- t, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
- remove = true;
- }
- else if (!cp_omp_mappable_type (TREE_TYPE (t)))
- {
- error_at (OMP_CLAUSE_LOCATION (c),
- "%qE does not have a mappable type in %qs clause",
- t, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
- cp_omp_emit_unmappable_type_notes (TREE_TYPE (t));
- remove = true;
- }
- while (TREE_CODE (t) == COMPONENT_REF)
- {
- 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);
- remove = true;
- break;
- }
- t = TREE_OPERAND (t, 0);
- if (TREE_CODE (t) == MEM_REF)
- {
- if (maybe_ne (mem_ref_offset (t), 0))
- error_at (OMP_CLAUSE_LOCATION (c),
- "cannot dereference %qE in %qs clause", t,
- omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
- else
- t = TREE_OPERAND (t, 0);
- }
- while (TREE_CODE (t) == MEM_REF
- || TREE_CODE (t) == INDIRECT_REF
- || TREE_CODE (t) == ARRAY_REF)
- {
- t = TREE_OPERAND (t, 0);
- STRIP_NOPS (t);
- if (TREE_CODE (t) == POINTER_PLUS_EXPR)
- t = TREE_OPERAND (t, 0);
- }
- }
- 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))
- || (ort != C_ORT_ACC
- && bitmap_bit_p (&map_head, DECL_UID (t))))
- goto handle_map_references;
- }
- }
- if (!processing_template_decl
- && TREE_CODE (t) == FIELD_DECL)
+ }
+ indir_component_ref_p = t_insp.indir_component_ref_p ();
+ if (t_insp.component_access_p ()
+ && (VAR_P (t) || TREE_CODE (t) == PARM_DECL))
+ {
+ if (bitmap_bit_p (&map_field_head, DECL_UID (t))
+ || (ort != C_ORT_ACC
+ && bitmap_bit_p (&map_head, DECL_UID (t))))
+ goto handle_map_references;
+ }
+ }
+
+ if (!processing_template_decl && TREE_CODE (t) == FIELD_DECL)
{
OMP_CLAUSE_DECL (c) = finish_non_static_data_member (t, NULL_TREE,
NULL_TREE);
new file mode 100644
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+
+struct A {
+ static int x[10];
+};
+
+struct B {
+ A a;
+};
+
+int
+main (int argc, char *argv[])
+{
+ B *b = new B;
+#pragma omp target map(b->a) // { dg-error "'b->B::a' does not have a mappable type in 'map' clause" }
+ ;
+ B bb;
+#pragma omp target map(bb.a) // { dg-error "'bb\.B::a' does not have a mappable type in 'map' clause" }
+ ;
+ delete b;
+}
new file mode 100644
@@ -0,0 +1,59 @@
+/* { dg-do run } */
+
+#include <cassert>
+
+#define N 1024
+
+class M {
+ int array[N];
+
+public:
+ M ()
+ {
+ for (int i = 0; i < N; i++)
+ array[i] = 0;
+ }
+
+ void incr_with_this (int c)
+ {
+#pragma omp target map(this->array[:N])
+ for (int i = 0; i < N; i++)
+ array[i] += c;
+ }
+
+ void incr_without_this (int c)
+ {
+#pragma omp target map(array[:N])
+ for (int i = 0; i < N; i++)
+ array[i] += c;
+ }
+
+ void incr_implicit (int c)
+ {
+#pragma omp target
+ for (int i = 0; i < N; i++)
+ array[i] += c;
+ }
+
+ void check (int c)
+ {
+ for (int i = 0; i < N; i++)
+ assert (array[i] == c);
+ }
+};
+
+int
+main (int argc, char *argv[])
+{
+ M m;
+
+ m.check (0);
+ m.incr_with_this (3);
+ m.check (3);
+ m.incr_without_this (5);
+ m.check (8);
+ m.incr_implicit (2);
+ m.check (10);
+
+ return 0;
+}