From patchwork Thu Aug 30 19:31:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julian Brown X-Patchwork-Id: 964138 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-484819-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="TNMl/FNI"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 421XgY5F4Jz9s0n for ; Fri, 31 Aug 2018 05:32:07 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=rKvamSxnLK1Bfvc31F9cndtbZQjZKACUMI1i1N7Tq5fBdCrFy3qRL OaAtxoSDRHPKsMMjDWtV8lZHrQ0SRSfZJIyjjrfe3cn1EwTXBFqopUV4WN4WAttK a2J+sljWBAqJaAeVG3qbKVrfMSNq4VkNAoRSW/UHfH4GlgmBd+eT2s= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=QJ3pWdwSmHwdy0LHNhaLiI3xUxE=; b=TNMl/FNIx5J9qsj0B0ai +dDo584QRBKBwHjsKwNM2TnTfuVINmqlccuYAE5Xzke008K8lx5GnFH77mesHHAK B0wYw0KCL0n5oWdooEvRos88rfSXqPfN8A9PUvOAfc+GDuBaXYYBd09UCHhtBbsO R66hZ1NQr5frvAufQKCVODA= Received: (qmail 64763 invoked by alias); 30 Aug 2018 19:32:00 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 64623 invoked by uid 89); 30 Aug 2018 19:31:54 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-24.5 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=duly, DECL_NAME, sk:cp_buil, sk:conditi 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; Thu, 30 Aug 2018 19:31:51 +0000 Received: from nat-ies.mentorg.com ([192.94.31.2] helo=SVR-IES-MBX-04.mgc.mentorg.com) by relay1.mentorg.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-SHA384:256) id 1fvSfV-0005up-00 from Julian_Brown@mentor.com ; Thu, 30 Aug 2018 12:31:49 -0700 Received: from squid.athome (137.202.0.90) by SVR-IES-MBX-04.mgc.mentorg.com (139.181.222.4) with Microsoft SMTP Server (TLS) id 15.0.1320.4; Thu, 30 Aug 2018 20:31:43 +0100 Date: Thu, 30 Aug 2018 15:31:34 -0400 From: Julian Brown To: , , Subject: [PATCH, OpenACC] Support C++ "this" in OpenACC directives (PR66053) Message-ID: <20180830153134.544d4bef@squid.athome> MIME-Version: 1.0 X-IsSubscribed: yes This patch (by Joseph) allows "this" to be used in OpenACC directives, following -- IIUC -- the behaviour of other compilers. The standard (as of OpenACC 2.5) does not appear to have explicit language either permitting or forbidding such usage. Joseph's original commentary is in the bug report (ca. 2015, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66053): "This patch, for gomp-4_0-branch, adds support for C++ "this" in OpenACC directives. (This patch does not do anything to handle OpenMP differently from OpenACC; that - bug 66053 - will need to be resolved for mainline, either deciding these cases should be accepted for OpenMP or making the parsing only accept them in OpenACC directives and not OpenMP ones.) "Apart from parsing, it's necessary to prevent the "cannot take the address of 'this', which is an rvalue expression" error from appearing when "this" is used in such contexts. This patch duly adds a new argument to cxx_mark_addressable (default false so callers don't all need to change) to allow disabling that error, passing that argument in all calls that seem relevant to OpenACC directives." AFAICT though, this attached version of the patch does still forbid "this" in OpenMP directives (apart from "declare simd"). I couldn't see that there was any change to the OpenMP spec language in 4.5. Tested with offloading to NVPTX and bootstrapped. OK to apply? Julian ChangeLog 20xx-xx-xx Joseph Myers PR C++/66053 gcc/cp/ * cp-tree.h (enum cxx_mark_addressable_flags): New. (cxx_mark_addressable): Use it. Adjust users. * parser.c (cp_parser_omp_var_list_no_open): Handle RID_THIS. * semantics.c (handle_omp_array_sections_1) (handle_omp_array_sections, finish_omp_reduction_clause) (finish_omp_clauses): Pass CXX_MARK_ADDRESSABLE_FLAGS_ALLOW_THIS to cxx_mark_addressable. Enforce "this" usage limitation only for OpenMP. * typeck.c (cp_build_array_ref): Adjust cxx_mark_addressble call. (cxx_mark_addressable): Handle CXX_MARK_ADDRESSABLE_FLAGS_ALLOW_THIS. libgomp/ * testsuite/libgomp.oacc-c++/this.C: New test. commit 12294a1345d981b72ef61d285057fb4c7e378fd7 Author: Julian Brown Date: Wed Aug 29 18:19:44 2018 -0700 Support C++ "this" in OpenACC directives 20xx-xx-xx Joseph Myers PR C++/66053 gcc/cp/ * cp-tree.h (enum cxx_mark_addressable_flags): New. (cxx_mark_addressable): Use it. Adjust users. * parser.c (cp_parser_omp_var_list_no_open): Handle RID_THIS. * semantics.c (handle_omp_array_sections_1) (handle_omp_array_sections, finish_omp_reduction_clause) (finish_omp_clauses): Pass CXX_MARK_ADDRESSABLE_FLAGS_ALLOW_THIS to cxx_mark_addressable. Enforce "this" usage limitation only for OpenMP. * typeck.c (cp_build_array_ref): Adjust cxx_mark_addressble call. (cxx_mark_addressable): Handle CXX_MARK_ADDRESSABLE_FLAGS_ALLOW_THIS. libgomp/ * testsuite/libgomp.oacc-c++/this.C: New test. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 43e452c..127e15a 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -7214,7 +7214,24 @@ extern void cxx_print_error_function (diagnostic_context *, struct diagnostic_info *); /* in typeck.c */ -extern bool cxx_mark_addressable (tree, bool = false); + +/* Flags for cxx_mark_addressable. */ + +enum cxx_mark_addressable_flags +{ + CXX_MARK_ADDRESSABLE_FLAGS_NONE = 0, + /* This is for ARRAY_REF construction - in that case we don't want + to look through VIEW_CONVERT_EXPR from VECTOR_TYPE to ARRAY_TYPE, + it is fine to use ARRAY_REFs for vector subscripts on vector + register variables. */ + CXX_MARK_ADDRESSABLE_FLAGS_ARRAY_REF = 1 << 0, + /* Allow `current_class_ptr' to be addressable. */ + CXX_MARK_ADDRESSABLE_FLAGS_ALLOW_THIS = 1 << 1 +}; + +extern bool cxx_mark_addressable (tree, + enum cxx_mark_addressable_flags flags + = CXX_MARK_ADDRESSABLE_FLAGS_NONE); extern int string_conv_p (const_tree, const_tree, int); extern tree cp_truthvalue_conversion (tree); extern tree condition_conversion (tree); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 92e6b40..0cf2526 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -31726,7 +31726,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, OMP_CLAUSE_CHAIN (u) = list; list = u; } - else + else if (decl != error_mark_node) list = tree_cons (decl, NULL_TREE, list); get_comma: diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 676de01..9a722df 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -4598,7 +4598,8 @@ handle_omp_array_sections_1 (tree c, tree t, vec &types, omp_clause_code_name[OMP_CLAUSE_CODE (c)]); return error_mark_node; } - else if (TREE_CODE (t) == PARM_DECL + else if (ort == C_ORT_OMP + && TREE_CODE (t) == PARM_DECL && DECL_ARTIFICIAL (t) && DECL_NAME (t) == this_identifier) { @@ -5101,7 +5102,8 @@ handle_omp_array_sections (tree c, enum c_omp_region_type ort) else OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_FIRSTPRIVATE_POINTER); if (OMP_CLAUSE_MAP_KIND (c2) != GOMP_MAP_FIRSTPRIVATE_POINTER - && !cxx_mark_addressable (t)) + && !cxx_mark_addressable (t, + CXX_MARK_ADDRESSABLE_FLAGS_ALLOW_THIS)) return false; OMP_CLAUSE_DECL (c2) = t; t = build_fold_addr_expr (first); @@ -5689,7 +5691,8 @@ finish_omp_reduction_clause (tree c, bool *need_default_ctor, bool *need_dtor) if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[1])) && !TYPE_REF_P (TREE_TYPE (OMP_CLAUSE_DECL (c)))) cxx_mark_addressable (decl_placeholder ? decl_placeholder - : OMP_CLAUSE_DECL (c)); + : OMP_CLAUSE_DECL (c), + CXX_MARK_ADDRESSABLE_FLAGS_ALLOW_THIS); tree omp_out = placeholder; tree omp_in = decl_placeholder ? decl_placeholder : convert_from_reference (OMP_CLAUSE_DECL (c)); @@ -5715,7 +5718,8 @@ finish_omp_reduction_clause (tree c, bool *need_default_ctor, bool *need_dtor) && TREE_CODE (stmts[4]) == DECL_EXPR); if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[3]))) cxx_mark_addressable (decl_placeholder ? decl_placeholder - : OMP_CLAUSE_DECL (c)); + : OMP_CLAUSE_DECL (c), + CXX_MARK_ADDRESSABLE_FLAGS_ALLOW_THIS); if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[4]))) cxx_mark_addressable (placeholder); tree omp_priv = decl_placeholder ? decl_placeholder @@ -6655,7 +6659,8 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) remove = true; } else if (!processing_template_decl - && !cxx_mark_addressable (t)) + && !cxx_mark_addressable (t, + CXX_MARK_ADDRESSABLE_FLAGS_ALLOW_THIS)) remove = true; break; @@ -6803,7 +6808,8 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP || (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER)) - && !cxx_mark_addressable (t)) + && !cxx_mark_addressable (t, + CXX_MARK_ADDRESSABLE_FLAGS_ALLOW_THIS)) remove = true; else if (!(OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index ab088a9..b24f3b2 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -3335,7 +3335,8 @@ cp_build_array_ref (location_t loc, tree array, tree idx, && (TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array)))) != INTEGER_CST))) { - if (!cxx_mark_addressable (array, true)) + if (!cxx_mark_addressable (array, + CXX_MARK_ADDRESSABLE_FLAGS_ARRAY_REF)) return error_mark_node; } @@ -6476,16 +6477,10 @@ unary_complex_lvalue (enum tree_code code, tree arg) /* Mark EXP saying that we need to be able to take the address of it; it should not be allocated in a register. - Value is true if successful. ARRAY_REF_P is true if this - is for ARRAY_REF construction - in that case we don't want - to look through VIEW_CONVERT_EXPR from VECTOR_TYPE to ARRAY_TYPE, - it is fine to use ARRAY_REFs for vector subscripts on vector - register variables. - - C++: we do not allow `current_class_ptr' to be addressable. */ + Value is true if successful. */ bool -cxx_mark_addressable (tree exp, bool array_ref_p) +cxx_mark_addressable (tree exp, enum cxx_mark_addressable_flags flags) { tree x = exp; @@ -6493,7 +6488,7 @@ cxx_mark_addressable (tree exp, bool array_ref_p) switch (TREE_CODE (x)) { case VIEW_CONVERT_EXPR: - if (array_ref_p + if ((flags & CXX_MARK_ADDRESSABLE_FLAGS_ARRAY_REF) && TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (x, 0)))) return true; @@ -6509,7 +6504,8 @@ cxx_mark_addressable (tree exp, bool array_ref_p) case PARM_DECL: if (x == current_class_ptr) { - error ("cannot take the address of %, which is an rvalue expression"); + if (!(flags & CXX_MARK_ADDRESSABLE_FLAGS_ALLOW_THIS)) + error ("cannot take the address of %, which is an rvalue expression"); TREE_ADDRESSABLE (x) = 1; /* so compiler doesn't die later. */ return true; } @@ -6552,7 +6548,7 @@ cxx_mark_addressable (tree exp, bool array_ref_p) case TARGET_EXPR: TREE_ADDRESSABLE (x) = 1; - cxx_mark_addressable (TREE_OPERAND (x, 0)); + cxx_mark_addressable (TREE_OPERAND (x, 0), flags); return true; default: diff --git a/libgomp/testsuite/libgomp.oacc-c++/this.C b/libgomp/testsuite/libgomp.oacc-c++/this.C new file mode 100644 index 0000000..5e70f3d --- /dev/null +++ b/libgomp/testsuite/libgomp.oacc-c++/this.C @@ -0,0 +1,43 @@ +#include +#include +using namespace std; + +class test { + public: + int a; + + test () + { + a = -1; +#pragma acc enter data copyin (this[0:1]) + } + + ~test () + { +#pragma acc exit data delete (this[0:1]) + } + + void set (int i) + { + a = i; +#pragma acc update device (this[0:1]) + } + + int get () + { +#pragma acc update host (this[0:1]) + return a; + } +}; + +int +main () +{ + test t; + + t.set (4); + if (t.get () != 4) + abort (); + + return 0; +}