From patchwork Thu Oct 15 17:56:04 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 530844 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 E15981402BF for ; Fri, 16 Oct 2015 04:56:20 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=Jop9mgWY; dkim-atps=neutral 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:reply-to:mime-version:content-type; q=dns; s=default; b=FZsxQlZpcSP4C+EgCfvIKvOPZ5S4cBJHBxBrl5aiolM TXq2I30+pSGrKiWG4l/AjKMAW3dkDLwaClHpZ8PDJ5EjZu/8+WUP9CCbz2ghGkXl ZR2jgH4pmScjWQMslMlxrnx/JF4TuBWS7lFt6Wkg1A8d/5YLX8HrunrRsxMARBVI = 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:reply-to:mime-version:content-type; s=default; bh=oY+Nlft4JsOpq/9Zs/5Q+Tum1HM=; b=Jop9mgWYw/8SW1Fr1 MBqck8a+4koz35Jv8f94rwRF0xQhOONbNaXeUhv7OTglA80+phIdQvnRhnHLoaPk P5R4+kx2w6BTEQyJae4tpa34IVn0vRtCXfq5Fr74uOU8OEOmpWWrcJjCd7n2GS9D nGj2urIpH3NdXdE7hWkN6kvEiM= Received: (qmail 126513 invoked by alias); 15 Oct 2015 17:56:12 -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 126501 invoked by uid 89); 15 Oct 2015 17:56:11 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Thu, 15 Oct 2015 17:56:09 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 4ACC68E704 for ; Thu, 15 Oct 2015 17:56:08 +0000 (UTC) Received: from tucnak.zalov.cz (ovpn-116-53.ams2.redhat.com [10.36.116.53]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9FHu6i3010350 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 15 Oct 2015 13:56:07 -0400 Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.15.2/8.15.2) with ESMTP id t9FHu5Li002876 for ; Thu, 15 Oct 2015 19:56:05 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id t9FHu4WV002875 for gcc-patches@gcc.gnu.org; Thu, 15 Oct 2015 19:56:04 +0200 Date: Thu, 15 Oct 2015 19:56:04 +0200 From: Jakub Jelinek To: gcc-patches@gcc.gnu.org Subject: [gomp4.5] declare target restrictions and clarifications Message-ID: <20151015175604.GH478@tucnak.redhat.com> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes Hi! This patch implements some new restrictions, clarifications etc. on the declare target construct. Committed to gomp-4_5-branch. 2015-10-15 Jakub Jelinek gcc/c/ * c-parser.c (c_parser_omp_declare_target): Call c_finish_omp_clauses in the parenthesized extended-list syntax case. * c-decl.c (c_decl_attributes): Don't diagnose block scope vars inside declare target. * c-typeck.c (c_finish_omp_clauses): Diagnose the same var or function appearing multiple times on the same directive. Fix up wording for the to clause if t is neither a FUNCTION_DECL nor a VAR_DECL. gcc/cp/ * parser.c (cp_parser_omp_declare_target): Call finish_omp_clauses in the parenthesized extended-list syntax case. Call cp_parser_require_pragma_eol instead of cp_parser_skip_to_pragma_eol. (cp_parser_omp_end_declare_target): Call cp_parser_require_pragma_eol instead of cp_parser_skip_to_pragma_eol. * decl2.c (cplus_decl_attributes): Don't diagnose block scope vars inside declare target. * semantics.c (finish_omp_clauses): Diagnose the same var or function appearing multiple times on the same directive. Fix up wording for the to clause if t is neither a FUNCTION_DECL nor a VAR_DECL, use special wording for OVERLOADs and TEMPLATE_ID_EXPR. gcc/testsuite/ * c-c++-common/gomp/declare-target-2.c: Add various new tests. Adjust expected diagnostics wording in one case. * g++.dg/gomp/declare-target-1.C: New test. libgomp/ * testsuite/libgomp.c/target-28.c: New test. * testsuite/libgomp.c++/target-13.C: New test. Jakub --- gcc/c/c-parser.c.jj 2015-10-14 18:04:13.000000000 +0200 +++ gcc/c/c-parser.c 2015-10-15 16:55:36.639169199 +0200 @@ -15531,6 +15531,7 @@ c_parser_omp_declare_target (c_parser *p { clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE, clauses); + clauses = c_finish_omp_clauses (clauses, true); c_parser_skip_to_pragma_eol (parser); } else --- gcc/c/c-decl.c.jj 2015-10-14 10:24:55.000000000 +0200 +++ gcc/c/c-decl.c 2015-10-15 19:24:50.809431612 +0200 @@ -4417,13 +4417,7 @@ c_decl_attributes (tree *node, tree attr || TREE_CODE (*node) == FUNCTION_DECL)) { if (VAR_P (*node) - && ((DECL_CONTEXT (*node) - && TREE_CODE (DECL_CONTEXT (*node)) == FUNCTION_DECL) - || (current_function_decl && !DECL_EXTERNAL (*node)))) - error ("%q+D in block scope inside of declare target directive", - *node); - else if (VAR_P (*node) - && !lang_hooks.types.omp_mappable_type (TREE_TYPE (*node))) + && !lang_hooks.types.omp_mappable_type (TREE_TYPE (*node))) error ("%q+D in declare target directive does not have mappable type", *node); else --- gcc/c/c-typeck.c.jj 2015-10-14 18:04:13.000000000 +0200 +++ gcc/c/c-typeck.c 2015-10-15 18:17:41.991147724 +0200 @@ -12837,17 +12837,22 @@ c_finish_omp_clauses (tree clauses, bool break; case OMP_CLAUSE_TO_DECLARE: - t = OMP_CLAUSE_DECL (c); - if (TREE_CODE (t) == FUNCTION_DECL) - break; - /* FALLTHRU */ case OMP_CLAUSE_LINK: t = OMP_CLAUSE_DECL (c); - if (!VAR_P (t)) + if (TREE_CODE (t) == FUNCTION_DECL + && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TO_DECLARE) + ; + else if (!VAR_P (t)) { - error_at (OMP_CLAUSE_LOCATION (c), - "%qE is not a variable in clause %qs", t, - omp_clause_code_name[OMP_CLAUSE_CODE (c)]); + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TO_DECLARE) + error_at (OMP_CLAUSE_LOCATION (c), + "%qE is neither a variable nor a function name in " + "clause %qs", t, + omp_clause_code_name[OMP_CLAUSE_CODE (c)]); + else + error_at (OMP_CLAUSE_LOCATION (c), + "%qE is not a variable in clause %qs", t, + omp_clause_code_name[OMP_CLAUSE_CODE (c)]); remove = true; } else if (DECL_THREAD_LOCAL_P (t)) @@ -12864,6 +12869,17 @@ c_finish_omp_clauses (tree clauses, bool omp_clause_code_name[OMP_CLAUSE_CODE (c)]); remove = true; } + if (remove) + break; + if (bitmap_bit_p (&generic_head, DECL_UID (t))) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%qE appears more than once on the same " + "% directive", t); + remove = true; + } + else + bitmap_set_bit (&generic_head, DECL_UID (t)); break; case OMP_CLAUSE_UNIFORM: --- gcc/cp/parser.c.jj 2015-10-14 18:04:13.000000000 +0200 +++ gcc/cp/parser.c 2015-10-15 17:36:30.206793453 +0200 @@ -34673,11 +34673,12 @@ cp_parser_omp_declare_target (cp_parser { clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_TO_DECLARE, clauses); - cp_parser_skip_to_pragma_eol (parser, pragma_tok); + clauses = finish_omp_clauses (clauses, true); + cp_parser_require_pragma_eol (parser, pragma_tok); } else { - cp_parser_skip_to_pragma_eol (parser, pragma_tok); + cp_parser_require_pragma_eol (parser, pragma_tok); scope_chain->omp_declare_target_attribute++; return; } @@ -34744,7 +34745,7 @@ cp_parser_omp_end_declare_target (cp_par cp_parser_skip_to_pragma_eol (parser, pragma_tok); return; } - cp_parser_skip_to_pragma_eol (parser, pragma_tok); + cp_parser_require_pragma_eol (parser, pragma_tok); if (!scope_chain->omp_declare_target_attribute) error_at (pragma_tok->location, "%<#pragma omp end declare target%> without corresponding " --- gcc/cp/decl2.c.jj 2015-10-14 10:25:31.000000000 +0200 +++ gcc/cp/decl2.c 2015-10-15 19:25:38.678722369 +0200 @@ -1454,11 +1454,6 @@ cplus_decl_attributes (tree *decl, tree && DECL_CLASS_SCOPE_P (*decl)) error ("%q+D static data member inside of declare target directive", *decl); - else if (VAR_P (*decl) - && (DECL_FUNCTION_SCOPE_P (*decl) - || (current_function_decl && !DECL_EXTERNAL (*decl)))) - error ("%q+D in block scope inside of declare target directive", - *decl); else if (!processing_template_decl && VAR_P (*decl) && !cp_omp_mappable_type (TREE_TYPE (*decl))) --- gcc/cp/semantics.c.jj 2015-10-14 18:04:13.000000000 +0200 +++ gcc/cp/semantics.c 2015-10-15 18:32:24.482064935 +0200 @@ -6521,17 +6521,33 @@ finish_omp_clauses (tree clauses, bool a break; case OMP_CLAUSE_TO_DECLARE: - t = OMP_CLAUSE_DECL (c); - if (TREE_CODE (t) == FUNCTION_DECL) - break; - /* FALLTHRU */ case OMP_CLAUSE_LINK: t = OMP_CLAUSE_DECL (c); - if (!VAR_P (t)) + if (TREE_CODE (t) == FUNCTION_DECL + && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TO_DECLARE) + ; + else if (!VAR_P (t)) { - error_at (OMP_CLAUSE_LOCATION (c), - "%qE is not a variable in clause %qs", t, - omp_clause_code_name[OMP_CLAUSE_CODE (c)]); + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TO_DECLARE) + { + if (TREE_CODE (t) == OVERLOAD && OVL_CHAIN (t)) + error_at (OMP_CLAUSE_LOCATION (c), + "overloaded function name %qE in clause %qs", t, + omp_clause_code_name[OMP_CLAUSE_CODE (c)]); + else if (TREE_CODE (t) == TEMPLATE_ID_EXPR) + error_at (OMP_CLAUSE_LOCATION (c), + "template %qE in clause %qs", t, + omp_clause_code_name[OMP_CLAUSE_CODE (c)]); + else + error_at (OMP_CLAUSE_LOCATION (c), + "%qE is neither a variable nor a function name " + "in clause %qs", t, + omp_clause_code_name[OMP_CLAUSE_CODE (c)]); + } + else + error_at (OMP_CLAUSE_LOCATION (c), + "%qE is not a variable in clause %qs", t, + omp_clause_code_name[OMP_CLAUSE_CODE (c)]); remove = true; } else if (DECL_THREAD_LOCAL_P (t)) @@ -6548,6 +6564,17 @@ finish_omp_clauses (tree clauses, bool a omp_clause_code_name[OMP_CLAUSE_CODE (c)]); remove = true; } + if (remove) + break; + if (bitmap_bit_p (&generic_head, DECL_UID (t))) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%qE appears more than once on the same " + "% directive", t); + remove = true; + } + else + bitmap_set_bit (&generic_head, DECL_UID (t)); break; case OMP_CLAUSE_UNIFORM: --- gcc/testsuite/c-c++-common/gomp/declare-target-2.c.jj 2015-10-14 10:25:30.000000000 +0200 +++ gcc/testsuite/c-c++-common/gomp/declare-target-2.c 2015-10-15 18:07:05.489584542 +0200 @@ -6,7 +6,7 @@ extern int a; #pragma omp declare target to (a) /* { dg-error "with clauses in between" } */ #pragma omp end declare target int b; -#pragma omp declare target to (b) link (b) /* { dg-error "specified both in declare target" } */ +#pragma omp declare target to (b) link (b) /* { dg-error "appears more than once on the same .declare target. directive" } */ int c; #pragma omp declare target (c) #pragma omp declare target link (c) /* { dg-error "specified both in declare target" } */ @@ -25,3 +25,21 @@ int g, h; #pragma omp declare target link (h) /* { dg-error "is threadprivate variable in" } */ int j[10]; #pragma omp declare target to (j[0:4]) /* { dg-error "expected" } */ +int k, l; +#pragma omp declare target +int m; +#pragma omp end declare target +#pragma omp declare target to (k) +#pragma omp declare target (k) +#pragma omp declare target to (k, m) link (l) +#pragma omp declare target link (l) +int n, o, s, t; +#pragma omp declare target to (n) to (n) /* { dg-error "appears more than once on the same .declare target. directive" } */ +#pragma omp declare target link (o, o) /* { dg-error "appears more than once on the same .declare target. directive" } */ +#pragma omp declare target (s, t, s) /* { dg-error "appears more than once on the same .declare target. directive" } */ +int p, q, r; +#pragma omp declare target (p) to (q) /* { dg-error "expected end of line before .to." } */ +#pragma omp declare target to (p) (q) link (r) /* { dg-error "expected .#pragma omp. clause before" } */ +#pragma omp declare target link (r) (p) /* { dg-error "expected .#pragma omp. clause before" } */ +#pragma omp declare target +#pragma omp end declare target to (p) /* { dg-error "expected end of line before .to." } */ --- gcc/testsuite/g++.dg/gomp/declare-target-1.C.jj 2015-10-15 18:09:08.043767545 +0200 +++ gcc/testsuite/g++.dg/gomp/declare-target-1.C 2015-10-15 19:11:29.037310874 +0200 @@ -0,0 +1,37 @@ +// { dg-do compile } +// { dg-options "-fopenmp" } + +#pragma omp declare target +void f1 (int); +void f1 (double); +template +void f2 (T); +template<> void f2 (int); +#pragma omp end declare target +void f3 (int); +void f4 (int); +void f4 (short); +template +void f5 (T); +#pragma omp declare target (f3) +#pragma omp declare target to (f4) // { dg-error "overloaded function name .f4. in clause .to." } +#pragma omp declare target to (f5) // { dg-error "template .f5. in clause .to." } +template +void f6 (int) +{ + static int s; + #pragma omp declare target (s) +} +namespace N +{ + namespace M + { + void f7 (int); + } + void f8 (long); +} +void f9 (short); +int v; +#pragma omp declare target (N::M::f7) +#pragma omp declare target to (::N::f8) +#pragma omp declare target to (::f9) to (::v) --- libgomp/testsuite/libgomp.c/target-28.c.jj 2015-10-15 18:56:27.932665314 +0200 +++ libgomp/testsuite/libgomp.c/target-28.c 2015-10-15 19:21:22.756514178 +0200 @@ -0,0 +1,33 @@ +extern void abort (void); + +#pragma omp declare target +int +foo (void) +{ + static int s; + return ++s; +} +#pragma omp end declare target + +int +bar (void) +{ + static int s; + #pragma omp declare target to (s) + return ++s; +} +#pragma omp declare target (bar) + +int +main () +{ + int r; + #pragma omp target map(from:r) + { + r = (foo () == 1) + (bar () == 1); + r += (foo () == 2) + (bar () == 2); + } + if (r != 4) + abort (); + return 0; +} --- libgomp/testsuite/libgomp.c++/target-13.C.jj 2015-10-15 19:27:52.179745374 +0200 +++ libgomp/testsuite/libgomp.c++/target-13.C 2015-10-15 19:29:00.188739477 +0200 @@ -0,0 +1,33 @@ +extern "C" void abort (void); + +#pragma omp declare target +int +foo (void) +{ + static int s; + return ++s; +} +#pragma omp end declare target + +int +bar (void) +{ + static int s; + #pragma omp declare target to (s) + return ++s; +} +#pragma omp declare target (bar) + +int +main () +{ + int r; + #pragma omp target map(from:r) + { + r = (foo () == 1) + (bar () == 1); + r += (foo () == 2) + (bar () == 2); + } + if (r != 4) + abort (); + return 0; +}