From 8862ed139a6ac3d28dc75ccbaa1dd36f47c8f9dd Mon Sep 17 00:00:00 2001 From: Andrew Stubbs Date: Thu, 4 Jul 2019 11:43:47 +0000 Subject: [PATCH] Improve OpenMP map diagnostics. 2019-07-04 Andrew Stubbs gcc/cp/ * cp-tree.h (cp_omp_emit_unmappable_type_notes): New prototype. * decl.c (cp_finish_decl): Call cp_omp_emit_unmappable_type_notes. * decl2.c (cp_omp_mappable_type): Move contents to ... (cp_omp_mappable_type_1): ... here and add note output. (cp_omp_emit_unmappable_type_notes): New function. * semantics.c (finish_omp_clauses): Call cp_omp_emit_unmappable_type_notes in four places. gcc/testsuite/ * g++.dg/gomp/unmappable-1.C: New file. From-SVN: r273078 --- gcc/cp/ChangeLog | 10 +++++ gcc/cp/cp-tree.h | 1 + gcc/cp/decl.c | 7 ++- gcc/cp/decl2.c | 54 ++++++++++++++++++++---- gcc/cp/semantics.c | 4 ++ gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/g++.dg/gomp/unmappable-1.C | 20 +++++++++ 7 files changed, 89 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/g++.dg/gomp/unmappable-1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7031d8d66bf..c1dfb7cee39 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2019-07-04 Andrew Stubbs + + * cp-tree.h (cp_omp_emit_unmappable_type_notes): New prototype. + * decl.c (cp_finish_decl): Call cp_omp_emit_unmappable_type_notes. + * decl2.c (cp_omp_mappable_type): Move contents to ... + (cp_omp_mappable_type_1): ... here and add note output. + (cp_omp_emit_unmappable_type_notes): New function. + * semantics.c (finish_omp_clauses): Call + cp_omp_emit_unmappable_type_notes in four places. + 2019-07-03 Martin Liska * call.c (build_new_op_1): Remove diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index a1849f69836..e814bc973f8 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6536,6 +6536,7 @@ 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.c */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index bb9d19a8172..a178b2208df 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -7433,8 +7433,11 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, DECL_ATTRIBUTES (decl)); complete_type (TREE_TYPE (decl)); if (!cp_omp_mappable_type (TREE_TYPE (decl))) - error ("%q+D in declare target directive does not have mappable type", - decl); + { + error ("%q+D in declare target directive does not have mappable" + " type", decl); + cp_omp_emit_unmappable_type_notes (TREE_TYPE (decl)); + } else if (!lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)) && !lookup_attribute ("omp declare target link", diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 206f04c6320..b415716c7dd 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1406,32 +1406,68 @@ cp_check_const_attributes (tree attributes) } } -/* Return true if TYPE is an OpenMP mappable type. */ -bool -cp_omp_mappable_type (tree type) +/* 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)) - return false; + { + if (notes) + { + 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); /* A mappable type cannot contain virtual members. */ if (CLASS_TYPE_P (type) && CLASSTYPE_VTABLES (type)) - return false; + { + if (notes) + inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)), + "type %qT with virtual members is not mappable", type); + result = false; + } /* 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)) - return false; + { + 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 (TREE_TYPE (field))) - return false; + && !cp_omp_mappable_type_1 (TREE_TYPE (field), notes)) + result = false; } - return true; + 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 diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 4f71ac706e5..cd24490bc6b 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -7090,6 +7090,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) "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)); remove = true; } while (TREE_CODE (t) == ARRAY_REF) @@ -7158,6 +7159,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) 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) @@ -7236,6 +7238,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) 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)); remove = true; } else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP @@ -7384,6 +7387,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) 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)); remove = true; } if (remove) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 89601758400..a974b11b5c2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-07-04 Andrew Stubbs + + * g++.dg/gomp/unmappable-1.C: New file. + 2019-07-04 Javier Miranda * gnat.dg/cpp_constructor.adb, gnat.dg/cpp_constructor_fp.ads, diff --git a/gcc/testsuite/g++.dg/gomp/unmappable-1.C b/gcc/testsuite/g++.dg/gomp/unmappable-1.C new file mode 100644 index 00000000000..d00ccb5ad79 --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/unmappable-1.C @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-fopenmp" } */ + +class C /* { dg-message "type .C. with virtual members is not mappable" } */ +{ +public: + static int static_member; /* { dg-message "static field .C::static_member. is not mappable" } */ + virtual void f() {} +}; + +extern C v[]; + +int +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 } */ + { + } +} -- 2.30.2