verify_type_context (location_t loc, type_context_kind context,
const_tree type, bool silent_p)
{
- if (!sizeless_type_p (type))
+ const_tree tmp = type;
+ if (omp_type_context (context) && POINTER_TYPE_P (type))
+ tmp = strip_pointer_types (tmp);
+
+ if (!sizeless_type_p (tmp))
return true;
switch (context)
if (!silent_p)
error_at (loc, "capture by copy of SVE type %qT", type);
return false;
+
+ case TCTX_OMP_MAP:
+ if (!silent_p)
+ error_at (loc, "SVE type %qT not allowed in %<map%> clause", type);
+ return false;
+
+ case TCTX_OMP_MAP_IMP_REF:
+ if (!silent_p)
+ error ("cannot reference %qT object types in %<target%> region", type);
+ return false;
+
+ case TCTX_OMP_PRIVATE:
+ if (!silent_p)
+ error_at (loc, "SVE type %qT not allowed in"
+ " %<target%> %<private%> clause", type);
+ return false;
+
+ case TCTX_OMP_FIRSTPRIVATE:
+ if (!silent_p)
+ error_at (loc, "SVE type %qT not allowed in"
+ " %<target%> %<firstprivate%> clause", type);
+ return false;
+
+ case TCTX_OMP_DEVICE_ADDR:
+ if (!silent_p)
+ error_at (loc, "SVE type %qT not allowed in"
+ " %<target%> device clauses", type);
+ return false;
+
+ default:
+ break;
}
gcc_unreachable ();
}
| GOVD_MAP_ALLOC_ONLY)) == flags)
{
tree type = TREE_TYPE (decl);
+ location_t loc = DECL_SOURCE_LOCATION (decl);
if (gimplify_omp_ctxp->target_firstprivatize_array_bases
&& omp_privatize_by_reference (decl))
type = TREE_TYPE (type);
- if (!omp_mappable_type (type))
+
+ if (!verify_type_context (loc, TCTX_OMP_MAP_IMP_REF, type))
+ /* Check if TYPE can appear in a target region.
+ verify_type_context has already issued an error if it
+ can't. */
+ nflags |= GOVD_MAP | GOVD_EXPLICIT;
+ else if (!omp_mappable_type (type))
{
error ("%qD referenced in target region does not have "
"a mappable type", decl);
unsigned int flags;
tree decl;
auto_vec<omp_addr_token *, 10> addr_tokens;
+ tree op = NULL_TREE;
+ location_t loc = OMP_CLAUSE_LOCATION (c);
if (grp_end && c == OMP_CLAUSE_CHAIN (grp_end))
{
grp_end = NULL_TREE;
}
+ if (code == OMP_TARGET
+ || code == OMP_TARGET_DATA
+ || code == OMP_TARGET_ENTER_DATA
+ || code == OMP_TARGET_EXIT_DATA)
+ /* Do some target-specific type checks for map operands. */
+ switch (OMP_CLAUSE_CODE (c))
+ {
+ case OMP_CLAUSE_MAP:
+ op = OMP_CLAUSE_OPERAND (c, 0);
+ verify_type_context (loc, TCTX_OMP_MAP, TREE_TYPE (op));
+ break;
+ case OMP_CLAUSE_PRIVATE:
+ op = OMP_CLAUSE_OPERAND (c, 0);
+ verify_type_context (loc, TCTX_OMP_PRIVATE, TREE_TYPE (op));
+ break;
+ case OMP_CLAUSE_FIRSTPRIVATE:
+ op = OMP_CLAUSE_OPERAND (c, 0);
+ verify_type_context (loc, TCTX_OMP_FIRSTPRIVATE, TREE_TYPE (op));
+ break;
+ case OMP_CLAUSE_IS_DEVICE_PTR:
+ case OMP_CLAUSE_USE_DEVICE_ADDR:
+ case OMP_CLAUSE_USE_DEVICE_PTR:
+ case OMP_CLAUSE_HAS_DEVICE_ADDR:
+ op = OMP_CLAUSE_OPERAND (c, 0);
+ verify_type_context (loc, TCTX_OMP_DEVICE_ADDR, TREE_TYPE (op));
+ break;
+ default:
+ break;
+ }
+
switch (OMP_CLAUSE_CODE (c))
{
case OMP_CLAUSE_PRIVATE:
TCTX_EXCEPTIONS,
/* Capturing objects of type T by value in a closure. */
- TCTX_CAPTURE_BY_COPY
+ TCTX_CAPTURE_BY_COPY,
+
+ /* Objects of type T appearing in OpenMP map clause. */
+ TCTX_OMP_MAP,
+
+ /* Objects of type T appearing in OpenMP target region
+ without explicit map. */
+ TCTX_OMP_MAP_IMP_REF,
+
+ /* Objects of type T appearing in OpenMP private clause. */
+ TCTX_OMP_PRIVATE,
+
+ /* Objects of type T appearing in OpenMP firstprivate clause. */
+ TCTX_OMP_FIRSTPRIVATE,
+
+ /* Objects of type T appearing in OpenMP device clauses. */
+ TCTX_OMP_DEVICE_ADDR
+
};
enum poly_value_estimate_kind
return true;
}
+/* Return true if OpenMP context types. */
+
+inline bool
+omp_type_context (type_context_kind context)
+{
+ switch (context)
+ {
+ case TCTX_OMP_MAP:
+ case TCTX_OMP_MAP_IMP_REF:
+ case TCTX_OMP_PRIVATE:
+ case TCTX_OMP_FIRSTPRIVATE:
+ case TCTX_OMP_DEVICE_ADDR:
+ return true;
+ default:
+ return false;
+ }
+}
+
#ifdef GCC_TM_H
#ifndef CUMULATIVE_ARGS_MAGIC