From patchwork Thu Nov 26 18:02:27 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 549206 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 16DD11402D5 for ; Fri, 27 Nov 2015 05:02:48 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=qpgO4QwW; 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:cc:subject:message-id:reply-to:mime-version :content-type; q=dns; s=default; b=dTYcq5C6hR4hMb/CA791pCdf8D38L WZE+lIuPAJb1PLD6aiSNQBu9FLSqkWjxSzIdrl4dShSd+T+bWaMR1mDswTMYWiDc 0MSf0ri60aT/CBuXbY+8UD5iAPhoGeLg0RagBcPEHLsEKpBGpF12fD0J1Bm6dIPd daAHZF6dRn/pc0= 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:cc:subject:message-id:reply-to:mime-version :content-type; s=default; bh=UCVAqtxJZD2DGoI8Z0+mKJ/6m50=; b=qpg O4QwWGvokGLB8OhFbl9HWzL2Xb1UBAP+hzbL2ViV4NmPrOf6ke9+GzDGHrAkSd5Z cfvL5G3ttdgjrmVFc/Xfc4qiAQ8dqOr6MebWh9pZDWV9O0DFtIpREUVmJbPPR0ei pCO4ObY/GGmQW2Lm3f7E5XFbX9z3S8rNmxFM0Xxk= Received: (qmail 32658 invoked by alias); 26 Nov 2015 18:02:38 -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 32648 invoked by uid 89); 26 Nov 2015 18:02:37 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS 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, 26 Nov 2015 18:02:35 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id 02A2B3B704; Thu, 26 Nov 2015 18:02:34 +0000 (UTC) Received: from tucnak.zalov.cz (ovpn-116-34.ams2.redhat.com [10.36.116.34]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAQI2Viv005838 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 26 Nov 2015 13:02:33 -0500 Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.15.2/8.15.2) with ESMTP id tAQI2T4Q000416; Thu, 26 Nov 2015 19:02:30 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id tAQI2RY4000415; Thu, 26 Nov 2015 19:02:27 +0100 Date: Thu, 26 Nov 2015 19:02:27 +0100 From: Jakub Jelinek To: "Joseph S. Myers" , Marek Polacek , Jason Merrill Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] Diagnose OpenMP standalone directives after labels (PR c/63326) Message-ID: <20151126180227.GJ5675@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! Old OpenMP standard versions for standalone directives just said that they shouldn't be placed in places where it would make a difference for parsing other statements whether the directive is ignored or not, later versions of the standard clarified it (not completely correctly) to after if, while, do, switch and label (clearly also missing other cases like after for, else). But what both C and C++ FEs implement is everything except after label. This patch attempts to change the C and C++ FEs to also use pragma_stmt on statements after labels (labeled-statement in C++ grammar). Bootstrapped/regtested on x86_64-linux and i686-linux, will commit tomorrow if there are no objections. 2015-11-26 Jakub Jelinek PR c/63326 * c-parser.c (c_parser_compound_statement_nostart): If last_label is true, use pragma_stmt instead of pragma_compound as second c_parser_pragma argument. (c_parser_omp_ordered, c_parser_omp_target_update, c_parser_omp_target_enter_data, c_parser_omp_target_exit_data): Pass false as second argument to c_parser_skip_to_pragma_eol after diagnosing standalone directives used in pragma_stmt context. * parser.c (cp_parser_statement): Clear in_compound after labels. * gcc.dg/gomp/barrier-2.c (f2): Expect another error after label. * c-c++-common/gomp/pr63326.c: New test. * testsuite/libgomp.c/cancel-parallel-2.c (foo): Add semicolon in between case label and OpenMP standalone directives. * testsuite/libgomp.c++/cancel-parallel-2.C (foo): Likewise. Jakub --- gcc/c/c-parser.c.jj 2015-11-25 09:49:54.000000000 +0100 +++ gcc/c/c-parser.c 2015-11-26 14:26:39.757928416 +0100 @@ -4729,7 +4729,8 @@ c_parser_compound_statement_nostart (c_p syntactically. This ensures that the user doesn't put them places that would turn into syntax errors if the directive were ignored. */ - if (c_parser_pragma (parser, pragma_compound)) + if (c_parser_pragma (parser, + last_label ? pragma_stmt : pragma_compound)) last_label = false, last_stmt = true; } else if (c_parser_next_token_is (parser, CPP_EOF)) @@ -14988,7 +14989,7 @@ c_parser_omp_ordered (c_parser *parser, error_at (loc, "%<#pragma omp ordered%> with % clause may " "only be used in compound statements"); - c_parser_skip_to_pragma_eol (parser); + c_parser_skip_to_pragma_eol (parser, false); return false; } @@ -15636,7 +15637,7 @@ c_parser_omp_target_update (location_t l error_at (loc, "%<#pragma omp target update%> may only be " "used in compound statements"); - c_parser_skip_to_pragma_eol (parser); + c_parser_skip_to_pragma_eol (parser, false); return false; } @@ -15696,7 +15697,7 @@ c_parser_omp_target_enter_data (location error_at (loc, "%<#pragma omp target enter data%> may only be " "used in compound statements"); - c_parser_skip_to_pragma_eol (parser); + c_parser_skip_to_pragma_eol (parser, false); return NULL_TREE; } @@ -15781,7 +15782,7 @@ c_parser_omp_target_exit_data (location_ error_at (loc, "%<#pragma omp target exit data%> may only be " "used in compound statements"); - c_parser_skip_to_pragma_eol (parser); + c_parser_skip_to_pragma_eol (parser, false); return NULL_TREE; } --- gcc/cp/parser.c.jj 2015-11-25 09:49:55.000000000 +0100 +++ gcc/cp/parser.c 2015-11-26 15:04:16.914842804 +0100 @@ -10003,6 +10003,7 @@ cp_parser_statement (cp_parser* parser, Parse the label, and then use tail recursion to parse the statement. */ cp_parser_label_for_labeled_statement (parser, std_attrs); + in_compound = false; goto restart; case RID_IF: @@ -10100,6 +10101,7 @@ cp_parser_statement (cp_parser* parser, the statement. */ cp_parser_label_for_labeled_statement (parser, std_attrs); + in_compound = false; goto restart; } } --- gcc/testsuite/gcc.dg/gomp/barrier-2.c.jj 2008-09-05 12:54:26.000000000 +0200 +++ gcc/testsuite/gcc.dg/gomp/barrier-2.c 2015-11-26 15:27:50.990679259 +0100 @@ -16,7 +16,7 @@ void f1(void) void f2(void) { label: /* { dg-error "label at end of compound statement" } */ - #pragma omp barrier + #pragma omp barrier /* { dg-error "may only be used in compound statements" } */ } void f3(_Bool p) --- gcc/testsuite/c-c++-common/gomp/pr63326.c.jj 2015-11-26 13:54:17.572711016 +0100 +++ gcc/testsuite/c-c++-common/gomp/pr63326.c 2015-11-26 15:15:01.658689775 +0100 @@ -0,0 +1,479 @@ +/* PR c/63326 */ +/* { dg-do compile } */ +/* { dg-options "-fopenmp" } */ + +void +f1 (int x) +{ + int i; + if (x) + #pragma omp barrier /* { dg-error "may only be used in compound statements" } */ + ; + if (x) + #pragma omp flush /* { dg-error "may only be used in compound statements" } */ + ; + if (x) + #pragma omp taskwait /* { dg-error "may only be used in compound statements" } */ + ; + if (x) + #pragma omp taskyield /* { dg-error "may only be used in compound statements" } */ + ; + #pragma omp parallel + { + if (x) + #pragma omp cancel parallel /* { dg-error "may only be used in compound statements" } */ + ; + } + #pragma omp parallel + { + if (x) + #pragma omp cancellation point parallel /* { dg-error "may only be used in compound statements" } */ + ; + } + #pragma omp for ordered(1) + for (i = 0; i < 16; i++) + { + if (x) + #pragma omp ordered depend(source) /* { dg-error "may only be used in compound statements" } */ + ; + if (x) + #pragma omp ordered depend(sink: i-1) /* { dg-error "may only be used in compound statements" } */ + ; + } + if (x) + #pragma omp target enter data map(to:i) /* { dg-error "may only be used in compound statements" } */ + ; + if (x) + #pragma omp target update to(i) /* { dg-error "may only be used in compound statements" } */ + ; + if (x) + #pragma omp target exit data map(from:i) /* { dg-error "may only be used in compound statements" } */ + ; +} + +void +f2 (int x) +{ + int i; + while (x) + #pragma omp barrier /* { dg-error "may only be used in compound statements" } */ + ; + while (x) + #pragma omp flush /* { dg-error "may only be used in compound statements" } */ + ; + while (x) + #pragma omp taskwait /* { dg-error "may only be used in compound statements" } */ + ; + while (x) + #pragma omp taskyield /* { dg-error "may only be used in compound statements" } */ + ; + #pragma omp parallel + { + while (x) + #pragma omp cancel parallel /* { dg-error "may only be used in compound statements" } */ + ; + } + #pragma omp parallel + { + while (x) + #pragma omp cancellation point parallel /* { dg-error "may only be used in compound statements" } */ + ; + } + #pragma omp for ordered(1) + for (i = 0; i < 16; i++) + { + while (x) + #pragma omp ordered depend(source) /* { dg-error "may only be used in compound statements" } */ + ; + while (x) + #pragma omp ordered depend(sink: i-1) /* { dg-error "may only be used in compound statements" } */ + ; + } + while (x) + #pragma omp target enter data map(to:i) /* { dg-error "may only be used in compound statements" } */ + ; + while (x) + #pragma omp target update to(i) /* { dg-error "may only be used in compound statements" } */ + ; + while (x) + #pragma omp target exit data map(from:i) /* { dg-error "may only be used in compound statements" } */ + ; +} + +void +f3 (int x) +{ + int i; + for (x = 0; x < 10; x++) + #pragma omp barrier /* { dg-error "may only be used in compound statements" } */ + ; + for (x = 0; x < 10; x++) + #pragma omp flush /* { dg-error "may only be used in compound statements" } */ + ; + for (x = 0; x < 10; x++) + #pragma omp taskwait /* { dg-error "may only be used in compound statements" } */ + ; + for (x = 0; x < 10; x++) + #pragma omp taskyield /* { dg-error "may only be used in compound statements" } */ + ; + #pragma omp parallel + { + for (x = 0; x < 10; x++) + #pragma omp cancel parallel /* { dg-error "may only be used in compound statements" } */ + ; + } + #pragma omp parallel + { + for (x = 0; x < 10; x++) + #pragma omp cancellation point parallel /* { dg-error "may only be used in compound statements" } */ + ; + } + #pragma omp for ordered(1) + for (i = 0; i < 16; i++) + { + for (x = 0; x < 10; x++) + #pragma omp ordered depend(source) /* { dg-error "may only be used in compound statements" } */ + ; + for (x = 0; x < 10; x++) + #pragma omp ordered depend(sink: i-1) /* { dg-error "may only be used in compound statements" } */ + ; + } + for (x = 0; x < 10; x++) + #pragma omp target enter data map(to:i) /* { dg-error "may only be used in compound statements" } */ + ; + for (x = 0; x < 10; x++) + #pragma omp target update to(i) /* { dg-error "may only be used in compound statements" } */ + ; + for (x = 0; x < 10; x++) + #pragma omp target exit data map(from:i) /* { dg-error "may only be used in compound statements" } */ + ; +} + +void +f4 (int x) +{ + int i; + { + do + #pragma omp barrier /* { dg-error "may only be used in compound statements" } */ + while (0); + } /* { dg-error "before" "" { target c++ } } */ + { + do + #pragma omp flush /* { dg-error "may only be used in compound statements" } */ + while (0); + } /* { dg-error "before" "" { target c++ } } */ + { + do + #pragma omp taskwait /* { dg-error "may only be used in compound statements" } */ + while (0); + } /* { dg-error "before" "" { target c++ } } */ + { + do + #pragma omp taskyield /* { dg-error "may only be used in compound statements" } */ + while (0); + } /* { dg-error "before" "" { target c++ } } */ + #pragma omp parallel + { + do + #pragma omp cancel parallel /* { dg-error "may only be used in compound statements" } */ + while (0); + } /* { dg-error "before" "" { target c++ } } */ + #pragma omp parallel + { + do + #pragma omp cancellation point parallel /* { dg-error "may only be used in compound statements" } */ + while (0); + } /* { dg-error "before" "" { target c++ } } */ + #pragma omp for ordered(1) + for (i = 0; i < 16; i++) + { + { + do + #pragma omp ordered depend(source) /* { dg-error "may only be used in compound statements" } */ + while (0); + } /* { dg-error "before" "" { target c++ } } */ + { + do + #pragma omp ordered depend(sink: i-1) /* { dg-error "may only be used in compound statements" } */ + while (0); + } /* { dg-error "before" "" { target c++ } } */ + } + { + do + #pragma omp target enter data map(to:i) /* { dg-error "may only be used in compound statements" } */ + while (0); + } /* { dg-error "before" "" { target c++ } } */ + { + do + #pragma omp target update to(i) /* { dg-error "may only be used in compound statements" } */ + while (0); + } /* { dg-error "before" "" { target c++ } } */ + { + do + #pragma omp target exit data map(from:i) /* { dg-error "may only be used in compound statements" } */ + while (0); + } /* { dg-error "before" "" { target c++ } } */ +} + +void +f5 (int x) +{ + int i; + switch (x) + #pragma omp barrier /* { dg-error "may only be used in compound statements" } */ + ; + switch (x) + #pragma omp flush /* { dg-error "may only be used in compound statements" } */ + ; + switch (x) + #pragma omp taskwait /* { dg-error "may only be used in compound statements" } */ + ; + switch (x) + #pragma omp taskyield /* { dg-error "may only be used in compound statements" } */ + ; + #pragma omp parallel + { + switch (x) + #pragma omp cancel parallel /* { dg-error "may only be used in compound statements" } */ + ; + } + #pragma omp parallel + { + switch (x) + #pragma omp cancellation point parallel /* { dg-error "may only be used in compound statements" } */ + ; + } + #pragma omp for ordered(1) + for (i = 0; i < 16; i++) + { + switch (x) + #pragma omp ordered depend(source) /* { dg-error "may only be used in compound statements" } */ + ; + switch (x) + #pragma omp ordered depend(sink: i-1) /* { dg-error "may only be used in compound statements" } */ + ; + } + switch (x) + #pragma omp target enter data map(to:i) /* { dg-error "may only be used in compound statements" } */ + ; + switch (x) + #pragma omp target update to(i) /* { dg-error "may only be used in compound statements" } */ + ; + switch (x) + #pragma omp target exit data map(from:i) /* { dg-error "may only be used in compound statements" } */ + ; +} + +void +f6 (int x) +{ + int i; + switch (x) + { + case 1: + #pragma omp barrier /* { dg-error "may only be used in compound statements" } */ + ; + } + switch (x) + { + case 1: + #pragma omp flush /* { dg-error "may only be used in compound statements" } */ + ; + } + switch (x) + { + case 1: + #pragma omp taskwait /* { dg-error "may only be used in compound statements" } */ + ; + } + switch (x) + { + case 1: + #pragma omp taskyield /* { dg-error "may only be used in compound statements" } */ + ; + } + #pragma omp parallel + { + switch (x) + { + case 1: + #pragma omp cancel parallel /* { dg-error "may only be used in compound statements" } */ + ; + } + } + #pragma omp parallel + { + switch (x) + { + case 1: + #pragma omp cancellation point parallel /* { dg-error "may only be used in compound statements" } */ + ; + } + } + #pragma omp for ordered(1) + for (i = 0; i < 16; i++) + { + switch (x) + { + case 1: + #pragma omp ordered depend(source) /* { dg-error "may only be used in compound statements" } */ + ; + } + switch (x) + { + case 1: + #pragma omp ordered depend(sink: i-1) /* { dg-error "may only be used in compound statements" } */ + ; + } + } + switch (x) + { + case 1: + #pragma omp target enter data map(to:i) /* { dg-error "may only be used in compound statements" } */ + ; + } + switch (x) + { + case 1: + #pragma omp target update to(i) /* { dg-error "may only be used in compound statements" } */ + ; + } + switch (x) + { + case 1: + #pragma omp target exit data map(from:i) /* { dg-error "may only be used in compound statements" } */ + ; + } +} + +void +f7 (int x) +{ + int i; + switch (x) + { + default: + #pragma omp barrier /* { dg-error "may only be used in compound statements" } */ + ; + } + switch (x) + { + default: + #pragma omp flush /* { dg-error "may only be used in compound statements" } */ + ; + } + switch (x) + { + default: + #pragma omp taskwait /* { dg-error "may only be used in compound statements" } */ + ; + } + switch (x) + { + default: + #pragma omp taskyield /* { dg-error "may only be used in compound statements" } */ + ; + } + #pragma omp parallel + { + switch (x) + { + default: + #pragma omp cancel parallel /* { dg-error "may only be used in compound statements" } */ + ; + } + } + #pragma omp parallel + { + switch (x) + { + default: + #pragma omp cancellation point parallel /* { dg-error "may only be used in compound statements" } */ + ; + } + } + #pragma omp for ordered(1) + for (i = 0; i < 16; i++) + { + switch (x) + { + default: + #pragma omp ordered depend(source) /* { dg-error "may only be used in compound statements" } */ + ; + } + switch (x) + { + default: + #pragma omp ordered depend(sink: i-1) /* { dg-error "may only be used in compound statements" } */ + ; + } + } + switch (x) + { + default: + #pragma omp target enter data map(to:i) /* { dg-error "may only be used in compound statements" } */ + ; + } + switch (x) + { + default: + #pragma omp target update to(i) /* { dg-error "may only be used in compound statements" } */ + ; + } + switch (x) + { + default: + #pragma omp target exit data map(from:i) /* { dg-error "may only be used in compound statements" } */ + ; + } +} + +void +f8 (int x) +{ + int i; + lab1: + #pragma omp barrier /* { dg-error "may only be used in compound statements" } */ + ; + lab2: + #pragma omp flush /* { dg-error "may only be used in compound statements" } */ + ; + lab3: + #pragma omp taskwait /* { dg-error "may only be used in compound statements" } */ + ; + lab4: + #pragma omp taskyield /* { dg-error "may only be used in compound statements" } */ + ; + #pragma omp parallel + { + lab5: + #pragma omp cancel parallel /* { dg-error "may only be used in compound statements" } */ + ; + } + #pragma omp parallel + { + lab6: + #pragma omp cancellation point parallel /* { dg-error "may only be used in compound statements" } */ + ; + } + #pragma omp for ordered(1) + for (i = 0; i < 16; i++) + { + lab7: + #pragma omp ordered depend(source) /* { dg-error "may only be used in compound statements" } */ + ; + lab8: + #pragma omp ordered depend(sink: i-1) /* { dg-error "may only be used in compound statements" } */ + ; + } + lab9: + #pragma omp target enter data map(to:i) /* { dg-error "may only be used in compound statements" } */ + ; + lab10: + #pragma omp target update to(i) /* { dg-error "may only be used in compound statements" } */ + ; + lab11: + #pragma omp target exit data map(from:i) /* { dg-error "may only be used in compound statements" } */ + ; +} --- libgomp/testsuite/libgomp.c/cancel-parallel-2.c.jj 2013-10-11 11:23:59.000000000 +0200 +++ libgomp/testsuite/libgomp.c/cancel-parallel-2.c 2015-11-26 15:35:47.477857521 +0100 @@ -13,7 +13,7 @@ foo (int *x) int thr = omp_get_thread_num (); switch (x[thr]) { - case 4: + case 4:; #pragma omp cancel parallel break; case 3: @@ -27,7 +27,7 @@ foo (int *x) case 2: usleep (1000); /* FALLTHRU */ - case 1: + case 1:; #pragma omp cancellation point parallel break; } --- libgomp/testsuite/libgomp.c++/cancel-parallel-2.C.jj 2013-10-11 11:23:59.000000000 +0200 +++ libgomp/testsuite/libgomp.c++/cancel-parallel-2.C 2015-11-26 15:36:04.280615978 +0100 @@ -17,7 +17,7 @@ foo (int *x) int thr = omp_get_thread_num (); switch (x[thr]) { - case 4: + case 4:; #pragma omp cancel parallel break; case 3: @@ -31,7 +31,7 @@ foo (int *x) case 2: usleep (1000); /* FALLTHRU */ - case 1: + case 1:; #pragma omp cancellation point parallel break; }