As this is the last lang-specific user of the omp_mappable_type hook,
the hook is removed, keeping only a generic omp_mappable_type for
incomplete types (or error_node).
PR c++/104493
gcc/c/ChangeLog:
* c-decl.cc (c_decl_attributes, finish_decl): Call omp_mappable_type
instead of removed langhook.
* c-typeck.cc (c_finish_omp_clauses): Likewise.
gcc/cp/ChangeLog:
* cp-objcp-common.h (LANG_HOOKS_OMP_MAPPABLE_TYPE): Remove.
* cp-tree.h (cp_omp_mappable_type, cp_omp_emit_unmappable_type_notes):
Remove.
* decl2.cc (cp_omp_mappable_type_1, cp_omp_mappable_type,
cp_omp_emit_unmappable_type_notes): Remove.
(cplus_decl_attributes): Call omp_mappable_type instead of
removed langhook.
* decl.cc (cp_finish_decl): Likewise; call cxx_incomplete_type_inform
in lieu of cp_omp_emit_unmappable_type_notes.
* semantics.cc (finish_omp_clauses): Likewise.
gcc/ChangeLog:
* gimplify.cc (omp_notice_variable): Call omp_mappable_type
instead of removed langhook.
* omp-general.h (omp_mappable_type): New prototype.
* omp-general.cc (omp_mappable_type): New; moved from ...
* langhooks.cc (lhd_omp_mappable_type): ... here.
* langhooks-def.h (lhd_omp_mappable_type,
LANG_HOOKS_OMP_MAPPABLE_TYPE): Remove.
(LANG_HOOKS_FOR_TYPES_INITIALIZER): Remote the latter.
* langhooks.h (struct lang_hooks_for_types): Remove
omp_mappable_type.
gcc/testsuite/ChangeLog:
* g++.dg/gomp/unmappable-1.C: Remove dg-error; remove dg-note no
longer shown as TYPE_MAIN_DECL is NULL.
* c-c++-common/gomp/map-incomplete-type.c: New test.
Co-authored-by: Chung-Lin Tang <cltang@codesourcery.com>
(cherry picked from commit
92a5de3df2dc958d6b3d18a0466189ad31f5ae79)
+2022-08-17 Tobias Burnus <tobias@codesourcery.com>
+
+ Backport from mainline:
+ 2022-08-17 Tobias Burnus <tobias@codesourcery.com>
+ Chung-Lin Tang <cltang@codesourcery.com>
+
+ PR c++/104493
+ * gimplify.cc (omp_notice_variable): Call omp_mappable_type
+ instead of removed langhook.
+ * omp-general.h (omp_mappable_type): New prototype.
+ * omp-general.cc (omp_mappable_type): New; moved from ...
+ * langhooks.cc (lhd_omp_mappable_type): ... here.
+ * langhooks-def.h (lhd_omp_mappable_type,
+ LANG_HOOKS_OMP_MAPPABLE_TYPE): Remove.
+ (LANG_HOOKS_FOR_TYPES_INITIALIZER): Remote the latter.
+ * langhooks.h (struct lang_hooks_for_types): Remove
+ omp_mappable_type.
+
2022-08-02 Andrew Stubbs <ams@codesourcery.com>
Backport from mainline:
+2022-08-17 Tobias Burnus <tobias@codesourcery.com>
+
+ Backport from mainline:
+ 2022-08-17 Tobias Burnus <tobias@codesourcery.com>
+ Chung-Lin Tang <cltang@codesourcery.com>
+
+ PR c++/104493
+ * c-decl.cc (c_decl_attributes, finish_decl): Call omp_mappable_type
+ instead of removed langhook.
+ * c-typeck.cc (c_finish_omp_clauses): Likewise.
+
2022-07-05 Tobias Burnus <tobias@codesourcery.com>
Backport from mainline:
&& ((VAR_P (*node) && is_global_var (*node))
|| TREE_CODE (*node) == FUNCTION_DECL))
{
- if (VAR_P (*node)
- && !lang_hooks.types.omp_mappable_type (TREE_TYPE (*node)))
+ if (VAR_P (*node) && !omp_mappable_type (TREE_TYPE (*node)))
attributes = tree_cons (get_identifier ("omp declare target implicit"),
NULL_TREE, attributes);
else
DECL_ATTRIBUTES (decl)
= remove_attribute ("omp declare target implicit",
DECL_ATTRIBUTES (decl));
- if (!lang_hooks.types.omp_mappable_type (TREE_TYPE (decl)))
+ if (!omp_mappable_type (TREE_TYPE (decl)))
error ("%q+D in declare target directive does not have mappable type",
decl);
else if (!lookup_attribute ("omp declare target",
else
{
t = OMP_CLAUSE_DECL (c);
- if (!lang_hooks.types.omp_mappable_type (TREE_TYPE (t)))
+ if (!omp_mappable_type (TREE_TYPE (t)))
{
error_at (OMP_CLAUSE_LOCATION (c),
"array section does not have mappable type "
t, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
remove = true;
}
- else if (!lang_hooks.types.omp_mappable_type (TREE_TYPE (t)))
+ else if (!omp_mappable_type (TREE_TYPE (t)))
{
error_at (OMP_CLAUSE_LOCATION (c),
"%qE does not have a mappable type in %qs clause",
|| (OMP_CLAUSE_MAP_KIND (c)
== GOMP_MAP_FORCE_DEVICEPTR)))
&& t == OMP_CLAUSE_DECL (c)
- && !lang_hooks.types.omp_mappable_type (TREE_TYPE (t)))
+ && !omp_mappable_type (TREE_TYPE (t)))
{
error_at (OMP_CLAUSE_LOCATION (c),
"%qD does not have a mappable type in %qs clause", t,
cname);
remove = true;
}
- else if (!lang_hooks.types.omp_mappable_type (TREE_TYPE (t)))
+ else if (!omp_mappable_type (TREE_TYPE (t)))
{
error_at (OMP_CLAUSE_LOCATION (c),
"%qD does not have a mappable type in %qs clause", t,
+2022-08-17 Tobias Burnus <tobias@codesourcery.com>
+
+ Backport from mainline:
+ 2022-08-17 Tobias Burnus <tobias@codesourcery.com>
+ Chung-Lin Tang <cltang@codesourcery.com>
+
+ PR c++/104493
+ * cp-objcp-common.h (LANG_HOOKS_OMP_MAPPABLE_TYPE): Remove.
+ * cp-tree.h (cp_omp_mappable_type, cp_omp_emit_unmappable_type_notes):
+ Remove.
+ * decl2.cc (cp_omp_mappable_type_1, cp_omp_mappable_type,
+ cp_omp_emit_unmappable_type_notes): Remove.
+ (cplus_decl_attributes): Call omp_mappable_type instead of
+ removed langhook.
+ * decl.cc (cp_finish_decl): Likewise; call cxx_incomplete_type_inform
+ in lieu of cp_omp_emit_unmappable_type_notes.
+ * semantics.cc (finish_omp_clauses): Likewise.
+
2022-07-29 Tobias Burnus <tobias@codesourcery.com>
Backport from mainline:
#define LANG_HOOKS_OMP_FINISH_CLAUSE cxx_omp_finish_clause
#undef LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE
#define LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE cxx_omp_privatize_by_reference
-#undef LANG_HOOKS_OMP_MAPPABLE_TYPE
-#define LANG_HOOKS_OMP_MAPPABLE_TYPE cp_omp_mappable_type
#undef LANG_HOOKS_OMP_DISREGARD_VALUE_EXPR
#define LANG_HOOKS_OMP_DISREGARD_VALUE_EXPR cxx_omp_disregard_value_expr
extern int parm_index (tree);
extern tree vtv_start_verification_constructor_init_function (void);
extern tree vtv_finish_verification_constructor_init_function (tree);
-extern bool cp_omp_mappable_type (tree);
-extern bool cp_omp_emit_unmappable_type_notes (tree);
extern void cp_check_const_attributes (tree);
/* in error.cc */
= remove_attribute ("omp declare target implicit",
DECL_ATTRIBUTES (decl));
complete_type (TREE_TYPE (decl));
- if (!cp_omp_mappable_type (TREE_TYPE (decl)))
+ if (!omp_mappable_type (TREE_TYPE (decl)))
{
error ("%q+D in declare target directive does not have mappable"
" type", decl);
- cp_omp_emit_unmappable_type_notes (TREE_TYPE (decl));
+ if (TREE_TYPE (decl) != error_mark_node
+ && !COMPLETE_TYPE_P (TREE_TYPE (decl)))
+ cxx_incomplete_type_inform (TREE_TYPE (decl));
}
else if (!lookup_attribute ("omp declare target",
DECL_ATTRIBUTES (decl))
#include "c-family/c-ada-spec.h"
#include "asan.h"
#include "optabs-query.h"
+#include "omp-general.h"
/* Id for dumping the raw trees. */
int raw_dump_id;
}
}
-/* Return true if TYPE is an OpenMP mappable type.
- If NOTES is non-zero, emit a note message for each problem. */
-static bool
-cp_omp_mappable_type_1 (tree type, bool notes)
-{
- bool result = true;
-
- /* Mappable type has to be complete. */
- if (type == error_mark_node || !COMPLETE_TYPE_P (type))
- {
- if (notes && type != error_mark_node)
- {
- tree decl = TYPE_MAIN_DECL (type);
- inform ((decl ? DECL_SOURCE_LOCATION (decl) : input_location),
- "incomplete type %qT is not mappable", type);
- }
- result = false;
- }
- /* Arrays have mappable type if the elements have mappable type. */
- while (TREE_CODE (type) == ARRAY_TYPE)
- type = TREE_TYPE (type);
- /* All data members must be non-static. */
- if (CLASS_TYPE_P (type))
- {
- tree field;
- for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
- if (VAR_P (field)
- /* Fields that are 'static constexpr' can be folded away at compile
- time, thus does not interfere with mapping. */
- && !DECL_DECLARED_CONSTEXPR_P (field))
- {
- if (notes)
- inform (DECL_SOURCE_LOCATION (field),
- "static field %qD is not mappable", field);
- result = false;
- }
- /* All fields must have mappable types. */
- else if (TREE_CODE (field) == FIELD_DECL
- && !cp_omp_mappable_type_1 (TREE_TYPE (field), notes))
- result = false;
- }
- return result;
-}
-
-/* Return true if TYPE is an OpenMP mappable type. */
-bool
-cp_omp_mappable_type (tree type)
-{
- return cp_omp_mappable_type_1 (type, false);
-}
-
-/* Return true if TYPE is an OpenMP mappable type.
- Emit an error messages if not. */
-bool
-cp_omp_emit_unmappable_type_notes (tree type)
-{
- return cp_omp_mappable_type_1 (type, true);
-}
-
/* Return the last pushed declaration for the symbol DECL or NULL
when no such declaration exists. */
*decl);
else if (VAR_P (*decl)
&& (processing_template_decl
- || !cp_omp_mappable_type (TREE_TYPE (*decl))))
+ || !omp_mappable_type (TREE_TYPE (*decl))))
attributes = tree_cons (get_identifier ("omp declare target implicit"),
NULL_TREE, attributes);
else
t = OMP_CLAUSE_DECL (c);
if (TREE_CODE (t) != TREE_LIST
&& !type_dependent_expression_p (t)
- && !cp_omp_mappable_type (TREE_TYPE (t)))
+ && !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)]);
- cp_omp_emit_unmappable_type_notes (TREE_TYPE (t));
+ if (TREE_TYPE (t) != error_mark_node
+ && !COMPLETE_TYPE_P (TREE_TYPE (t)))
+ cxx_incomplete_type_inform (TREE_TYPE (t));
remove = true;
}
while (TREE_CODE (t) == ARRAY_REF)
t, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
remove = true;
}
- else if (!cp_omp_mappable_type (TREE_TYPE (t)))
+ else if (!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));
+ if (TREE_TYPE (t) != error_mark_node
+ && !COMPLETE_TYPE_P (TREE_TYPE (t)))
+ cxx_incomplete_type_inform (TREE_TYPE (t));
remove = true;
}
while (TREE_CODE (t) == COMPONENT_REF)
== GOMP_MAP_FIRSTPRIVATE_POINTER)))
&& t == OMP_CLAUSE_DECL (c)
&& !type_dependent_expression_p (t)
- && !cp_omp_mappable_type (TYPE_REF_P (TREE_TYPE (t))
- ? TREE_TYPE (TREE_TYPE (t))
- : TREE_TYPE (t)))
+ && !omp_mappable_type (TYPE_REF_P (TREE_TYPE (t))
+ ? 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)]);
- cp_omp_emit_unmappable_type_notes (TREE_TYPE (t));
+ if (TREE_TYPE (t) != error_mark_node
+ && !COMPLETE_TYPE_P (TREE_TYPE (t)))
+ cxx_incomplete_type_inform (TREE_TYPE (t));
remove = true;
}
else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
cname);
remove = true;
}
- else if (!cp_omp_mappable_type (TREE_TYPE (t)))
+ else if (!omp_mappable_type (TREE_TYPE (t)))
{
error_at (OMP_CLAUSE_LOCATION (c),
"%qD does not have a mappable type in %qs clause", t,
cname);
- cp_omp_emit_unmappable_type_notes (TREE_TYPE (t));
+ if (TREE_TYPE (t) != error_mark_node
+ && !COMPLETE_TYPE_P (TREE_TYPE (t)))
+ cxx_incomplete_type_inform (TREE_TYPE (t));
remove = true;
}
if (remove)
if (gimplify_omp_ctxp->target_firstprivatize_array_bases
&& omp_privatize_by_reference (decl))
type = TREE_TYPE (type);
- if (!lang_hooks.types.omp_mappable_type (type))
+ if (!omp_mappable_type (type))
{
error ("%qD referenced in target region does not have "
"a mappable type", decl);
struct gimplify_omp_ctx;
extern void lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *,
tree);
-extern bool lhd_omp_mappable_type (tree);
extern bool lhd_omp_scalar_p (tree, bool);
extern tree *lhd_omp_get_decl_init (tree);
extern void lhd_omp_finish_decl_inits ();
#define LANG_HOOKS_TYPE_MAX_SIZE lhd_return_null_const_tree
#define LANG_HOOKS_OMP_FIRSTPRIVATIZE_TYPE_SIZES \
lhd_omp_firstprivatize_type_sizes
-#define LANG_HOOKS_OMP_MAPPABLE_TYPE lhd_omp_mappable_type
#define LANG_HOOKS_TYPE_HASH_EQ NULL
#define LANG_HOOKS_COPY_LANG_QUALIFIERS NULL
#define LANG_HOOKS_GET_ARRAY_DESCR_INFO NULL
LANG_HOOKS_INCOMPLETE_TYPE_ERROR, \
LANG_HOOKS_TYPE_MAX_SIZE, \
LANG_HOOKS_OMP_FIRSTPRIVATIZE_TYPE_SIZES, \
- LANG_HOOKS_OMP_MAPPABLE_TYPE, \
LANG_HOOKS_TYPE_HASH_EQ, \
LANG_HOOKS_COPY_LANG_QUALIFIERS, \
LANG_HOOKS_GET_ARRAY_DESCR_INFO, \
{
}
-/* Return true if TYPE is an OpenMP mappable type. */
-
-bool
-lhd_omp_mappable_type (tree type)
-{
- /* Mappable type has to be complete. */
- if (type == error_mark_node || !COMPLETE_TYPE_P (type))
- return false;
- return true;
-}
-
/* Common function for add_builtin_function, add_builtin_function_ext_scope
and simulate_builtin_function_decl. */
firstprivate variables. */
void (*omp_firstprivatize_type_sizes) (struct gimplify_omp_ctx *, tree);
- /* Return true if TYPE is a mappable type. */
- bool (*omp_mappable_type) (tree type);
-
/* Return TRUE if TYPE1 and TYPE2 are identical for type hashing purposes.
Called only after doing all language independent checks.
At present, this function is only called when both TYPE1 and TYPE2 are
return lang_hooks.decls.omp_check_optional_argument (decl, for_present_check);
}
+/* Return true if TYPE is an OpenMP mappable type. */
+
+bool
+omp_mappable_type (tree type)
+{
+ /* Mappable type has to be complete. */
+ if (type == error_mark_node || !COMPLETE_TYPE_P (type))
+ return false;
+ return true;
+}
+
/* True if OpenMP should privatize what this DECL points to rather
than the DECL itself. */
extern tree omp_find_clause (tree clauses, enum omp_clause_code kind);
extern bool omp_is_allocatable_or_ptr (tree decl);
extern tree omp_check_optional_argument (tree decl, bool for_present_check);
+extern bool omp_mappable_type (tree type);
extern bool omp_privatize_by_reference (tree decl);
extern void omp_adjust_for_condition (location_t loc, enum tree_code *cond_code,
tree *n2, tree v, tree step);
+2022-08-17 Tobias Burnus <tobias@codesourcery.com>
+
+ Backport from mainline:
+ 2022-08-17 Tobias Burnus <tobias@codesourcery.com>
+ Chung-Lin Tang <cltang@codesourcery.com>
+
+ PR c++/104493
+ * g++.dg/gomp/unmappable-1.C: Remove dg-error; remove dg-note no
+ longer shown as TYPE_MAIN_DECL is NULL.
+ * c-c++-common/gomp/map-incomplete-type.c: New test.
+
2022-07-29 Tobias Burnus <tobias@codesourcery.com>
Backport from mainline:
--- /dev/null
+struct incomplete_t;
+/* { dg-note "forward declaration of 'struct incomplete_t'" "" { target c++ } .-1 } */
+
+/* Note: This note is only printed with C++ (trice); the loc is available due to TYPE_MAIN_DECL. */
+
+struct incomplete_t *ptr;
+int i;
+
+void
+foo (void)
+{
+ #pragma omp target enter data map(to: i) map(to: ptr[0])
+ /* All apply to the line above. The first error is printed twice. */
+ /* { dg-error "invalid use of undefined type 'struct incomplete_t'" "" { target c } .-2 } */
+ /* { dg-error "invalid use of incomplete type 'struct incomplete_t'" "" { target c++ } .-3 } */
+ /* { dg-error "array section does not have mappable type in 'map' clause" "" { target *-*-* } .-4 } */
+}
class C
{
public:
- static int static_member; /* { dg-message "static field .C::static_member. is not mappable" } */
+ static int static_member;
virtual void f() {}
};
main ()
{
#pragma omp target map(v) /* { dg-error ".v. does not have a mappable type in .map. clause" } */
- /* { dg-message "incomplete type .C \\\[\\\]. is not mappable" "" { target *-*-* } .-1 } */
{
}
}