From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 88918 invoked by alias); 28 Jun 2019 10:46:24 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 88650 invoked by uid 89); 28 Jun 2019 10:46:24 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-17.7 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 spammy=component_ref, typedefs, field_decl, nonstatic X-HELO: relay1.mentorg.com Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 28 Jun 2019 10:46:22 +0000 Received: from nat-ies.mentorg.com ([192.94.31.2] helo=svr-ies-mbx-01.mgc.mentorg.com) by relay1.mentorg.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-SHA384:256) id 1hgoOY-0001TN-4P from Andrew_Stubbs@mentor.com for gcc-patches@gcc.gnu.org; Fri, 28 Jun 2019 03:46:18 -0700 Received: from [127.0.0.1] (137.202.0.90) by svr-ies-mbx-01.mgc.mentorg.com (139.181.222.1) with Microsoft SMTP Server (TLS) id 15.0.1320.4; Fri, 28 Jun 2019 11:46:14 +0100 From: Andrew Stubbs Subject: [patch, c++ openmp] Improve diagnostics for unmappable types To: "gcc-patches@gcc.gnu.org" Message-ID: <9471094d-05b6-0196-02c5-f7868f139332@codesourcery.com> Date: Fri, 28 Jun 2019 10:46:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.7.1 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------6CAC2D5484E432073B91144D" X-SW-Source: 2019-06/txt/msg01839.txt.bz2 --------------6CAC2D5484E432073B91144D Content-Type: text/plain; charset="utf-8"; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1304 This patch improves the diagnostics given for unmappable C++ types in OpenMP programs. Here is the output *without* the patch, for the new testcase: ---- unmappable-1.C: In function 'int main()': unmappable-1.C:16:24: error: 'v' does not have a mappable type in 'map' clause 16 | #pragma omp target map(v) ---- This is correct, but not very helpful for anything but the most trivial C++ types. Anything involving inheritance, templates, typedefs, etc. could be extremely difficult to track down. With the patch applied we now get this (I removed the "dg-message" comments for clarity): ---- unmappable-1.C: In function 'int main()': unmappable-1.C:16:24: error: 'v' does not have a mappable type in 'map' clause 16 | #pragma omp target map(v) | ^ cc1plus: note: incomplete types are not mappable unmappable-1.C:4:7: note: types with virtual members are not mappable 4 | class C | ^ unmappable-1.C:7:14: note: static fields are not mappable 7 | static int static_member; | ^~~~~~~~~~~~~ ---- The compiler now reports all the problematic fields in the whole type, recursively. If anybody knows how to report the location of incomplete array declarations then that would be nice to add. OK to commit? Andrew --------------6CAC2D5484E432073B91144D Content-Type: text/x-patch; name="190628-gcc-unmappable.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="190628-gcc-unmappable.patch" Content-length: 6576 Improve OpenMP map diagnostics. 2019-06-27 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. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index bf47f67721e..a7b2151e6dd 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6533,6 +6533,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 5d49535b0d9..74343bc1ec4 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..17deeda75f8 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1406,32 +1406,83 @@ 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) : UNKNOWN_LOCATION), + "incomplete types are not mappable"); + result = false; + } + else + 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; + { + if (notes) + { + inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)), + "types with virtual members are not mappable"); + result = false; + } + else + return 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 fields are not mappable"); + result = false; + } + else + return 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)) + { + if (notes) + result = false; + else + return 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 92c48753d42..8f019580d0f 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/g++.dg/gomp/unmappable-1.C b/gcc/testsuite/g++.dg/gomp/unmappable-1.C new file mode 100644 index 00000000000..29739240620 --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/unmappable-1.C @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-fopenmp" } */ + +class C /* { dg-message "types with virtual members are not mappable" } */ +{ +public: + static int static_member; /* { dg-message "static fields are not mappable" } */ + virtual void f() {} +}; + +extern C v[]; /* { dg-message "note: incomplete types are not mappable" "" { target *-*-* } 0 } */ + +int +main () +{ +#pragma omp target map(v) /* { dg-error ".v. does not have a mappable type in .map. clause" } */ + { + } +} --------------6CAC2D5484E432073B91144D--