This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Diagnose OpenMP standalone directives after labels (PR c/63326)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: "Joseph S. Myers" <joseph at codesourcery dot com>, Marek Polacek <polacek at redhat dot com>, Jason Merrill <jason at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 26 Nov 2015 19:02:27 +0100
- Subject: [PATCH] Diagnose OpenMP standalone directives after labels (PR c/63326)
- Authentication-results: sourceware.org; auth=none
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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 <jakub@redhat.com>
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.
--- 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 %<depend> 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;
}
Jakub