This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Diagnose OpenMP standalone directives after labels (PR c/63326)


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]