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]

[gomp] Fix C++ break in switch inside of #pragma omp for (PR c++/24516)


Hi!

If cp_parser_jump_statement is supposed to do the diagnostics about
break/continue in omp structured blocks and #pragma omp for, then I think
we need to track switch bit in the same var as well.  Otherwise, we don't
know if we are seeing:
#pragma omp for
  for (i = 0; i < 2; i++)
    switch (i)
      {
      case 1:
	break;	/* Shouldn't error here.  */
      }
or
switch (n)
  {
  case 1:
#pragma omp for
    for (i = 0; i < 2; i++)
      {
	break;  /* Should error here.  */
      }
  }

Ok for gomp or do you want to rewrite it RSN to something similar to
diagnose_omp_structured_block_errors that would work on FE trees?

2005-10-25  Jakub Jelinek  <jakub@redhat.com>

	PR c++/24516
	* parser.c (struct cp_parser): Rename in_iteration_statement
	field to in_statement.
	(IN_SWITCH_STMT, IN_ITERATION_STMT): Define.
	(IN_OMP_BLOCK, IN_OMP_FOR): Change values.
	(cp_parser_new, cp_parser_begin_omp_structured_block,
	cp_parser_end_omp_structured_block, cp_parser_omp_for_loop): Adjust
	for in_iteration_statement renaming.
	(cp_parser_selection_statement): Save parser->in_iteration, or it
	temporarily with IN_SWITCH_STMT for the
	cp_parser_implicitly_scoped_statement call.
	(cp_parser_iteration_statement): Adjust for in_iteration_statement
	renaming.  Use IN_ITERATION_STMT rather than true.
	(cp_parser_jump_statement): Adjust for in_iteration_statement
	renaming and new values.  Don't error on break in a switch statement
	within OMP_FOR or OpenMP structured block.

	* gcc.dg/gomp/block-11.c: New test.
	* g++.dg/gomp/block-11.C: New test.

--- gcc/cp/parser.c.jj	2005-10-25 11:17:18.000000000 +0200
+++ gcc/cp/parser.c	2005-10-25 16:57:19.000000000 +0200
@@ -1284,11 +1284,16 @@ typedef struct cp_parser GTY(())
   /* TRUE if we are presently parsing a template-argument-list.  */
   bool in_template_argument_list_p;
 
-  /* If we are presently parsing the body of an iteration-statement.
-     Takes 4 values: false, true, IN_OMP_BLOCK and IN_OMP_FOR.  */
-#define IN_OMP_BLOCK 2
-#define IN_OMP_FOR 3
-  unsigned char in_iteration_statement;
+  /* Set to IN_ITERATION_STMT if parsing an iteration-statement,
+     to IN_OMP_BLOCK if parsing OpenMP structured block and
+     IN_OMP_FOR if parsing OpenMP loop.  If parsing a switch statement,
+     this is bitwise ORed with IN_SWITCH_STMT, unless parsing an
+     iteration-statement, OpenMP block or loop within that switch.  */
+#define IN_SWITCH_STMT		1
+#define IN_ITERATION_STMT	2
+#define IN_OMP_BLOCK		4
+#define IN_OMP_FOR		8
+  unsigned char in_statement;
 
   /* TRUE if we are presently parsing the body of a switch statement.  */
   bool in_switch_statement_p;
@@ -2492,7 +2497,7 @@ cp_parser_new (void)
   parser->in_template_argument_list_p = false;
 
   /* We are not in an iteration statement.  */
-  parser->in_iteration_statement = false;
+  parser->in_statement = 0;
 
   /* We are not in a switch statement.  */
   parser->in_switch_statement_p = false;
@@ -6417,15 +6422,19 @@ cp_parser_selection_statement (cp_parser
 	else
 	  {
 	    bool in_switch_statement_p;
+	    unsigned char in_statement;
 
 	    /* Add the condition.  */
 	    finish_switch_cond (condition, statement);
 
 	    /* Parse the body of the switch-statement.  */
 	    in_switch_statement_p = parser->in_switch_statement_p;
+	    in_statement = parser->in_statement;
 	    parser->in_switch_statement_p = true;
+	    parser->in_statement |= IN_SWITCH_STMT;
 	    cp_parser_implicitly_scoped_statement (parser);
 	    parser->in_switch_statement_p = in_switch_statement_p;
+	    parser->in_statement = in_statement;
 
 	    /* Now we're all done with the switch-statement.  */
 	    finish_switch_stmt (statement);
@@ -6551,7 +6560,7 @@ cp_parser_iteration_statement (cp_parser
   cp_token *token;
   enum rid keyword;
   tree statement;
-  unsigned char in_iteration_statement;
+  unsigned char in_statement;
 
   /* Peek at the next token.  */
   token = cp_parser_require (parser, CPP_KEYWORD, "iteration-statement");
@@ -6560,7 +6569,7 @@ cp_parser_iteration_statement (cp_parser
 
   /* Remember whether or not we are already within an iteration
      statement.  */
-  in_iteration_statement = parser->in_iteration_statement;
+  in_statement = parser->in_statement;
 
   /* See what kind of keyword it is.  */
   keyword = token->keyword;
@@ -6580,9 +6589,9 @@ cp_parser_iteration_statement (cp_parser
 	/* Look for the `)'.  */
 	cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
 	/* Parse the dependent statement.  */
-	parser->in_iteration_statement = true;
+	parser->in_statement = IN_ITERATION_STMT;
 	cp_parser_already_scoped_statement (parser);
-	parser->in_iteration_statement = in_iteration_statement;
+	parser->in_statement = in_statement;
 	/* We're done with the while-statement.  */
 	finish_while_stmt (statement);
       }
@@ -6595,9 +6604,9 @@ cp_parser_iteration_statement (cp_parser
 	/* Begin the do-statement.  */
 	statement = begin_do_stmt ();
 	/* Parse the body of the do-statement.  */
-	parser->in_iteration_statement = true;
+	parser->in_statement = IN_ITERATION_STMT;
 	cp_parser_implicitly_scoped_statement (parser);
-	parser->in_iteration_statement = in_iteration_statement;
+	parser->in_statement = in_statement;
 	finish_do_body (statement);
 	/* Look for the `while' keyword.  */
 	cp_parser_require_keyword (parser, RID_WHILE, "`while'");
@@ -6642,9 +6651,9 @@ cp_parser_iteration_statement (cp_parser
 	cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
 
 	/* Parse the body of the for-statement.  */
-	parser->in_iteration_statement = true;
+	parser->in_statement = IN_ITERATION_STMT;
 	cp_parser_already_scoped_statement (parser);
-	parser->in_iteration_statement = in_iteration_statement;
+	parser->in_statement = in_statement;
 
 	/* We're done with the for-statement.  */
 	finish_for_stmt (statement);
@@ -6724,12 +6733,14 @@ cp_parser_jump_statement (cp_parser* par
   switch (keyword)
     {
     case RID_BREAK:
-      switch (parser->in_iteration_statement | parser->in_switch_statement_p)
+      switch (parser->in_statement)
 	{
-	case false:
+	case 0:
 	  error ("break statement not within loop or switch");
 	  break;
-	case true:
+	default:
+	  gcc_assert ((parser->in_statement & IN_SWITCH_STMT)
+		      || parser->in_statement == IN_ITERATION_STMT);
 	  statement = finish_break_stmt ();
 	  break;
 	case IN_OMP_BLOCK:
@@ -6738,19 +6749,17 @@ cp_parser_jump_statement (cp_parser* par
 	case IN_OMP_FOR:
 	  error ("break statement used with OpenMP for loop");
 	  break;
-	default:
-	  gcc_unreachable ();
 	}
       cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
       break;
 
     case RID_CONTINUE:
-      switch (parser->in_iteration_statement)
+      switch (parser->in_statement & ~IN_SWITCH_STMT)
 	{
-	case false:
+	case 0:
 	  error ("continue statement not within a loop");
 	  break;
-	case true:
+	case IN_ITERATION_STMT:
 	case IN_OMP_FOR:
 	  statement = finish_continue_stmt ();
 	  break;
@@ -18042,7 +18051,7 @@ cp_parser_omp_all_clauses (cp_parser *pa
 static unsigned
 cp_parser_begin_omp_structured_block (cp_parser *parser)
 {
-  unsigned save = parser->in_iteration_statement;
+  unsigned save = parser->in_statement;
 
   /* Only move the values to IN_OMP_BLOCK if they weren't false.
      This preserves the "not within loop or switch" style error messages
@@ -18052,8 +18061,8 @@ cp_parser_begin_omp_structured_block (cp
 	  break;
 	}
   */
-  if (parser->in_iteration_statement)
-    parser->in_iteration_statement = IN_OMP_BLOCK;
+  if (parser->in_statement)
+    parser->in_statement = IN_OMP_BLOCK;
 
   return save;
 }
@@ -18061,7 +18070,7 @@ cp_parser_begin_omp_structured_block (cp
 static void
 cp_parser_end_omp_structured_block (cp_parser *parser, unsigned save)
 {
-  parser->in_iteration_statement = save;
+  parser->in_statement = save;
 }
 
 static tree
@@ -18311,7 +18320,7 @@ cp_parser_omp_for_loop (cp_parser *parse
 
   /* Note that we saved the original contents of this flag when we entered
      the structured block, and so we don't need to re-save it here.  */
-  parser->in_iteration_statement = IN_OMP_FOR;
+  parser->in_statement = IN_OMP_FOR;
 
   /* Note that the grammar doesn't call for a structured block here,
      though the loop as a whole is a structured block.  */
--- gcc/testsuite/gcc.dg/gomp/block-11.c.jj	2005-10-25 17:03:29.000000000 +0200
+++ gcc/testsuite/gcc.dg/gomp/block-11.c	2005-10-25 17:03:03.000000000 +0200
@@ -0,0 +1,19 @@
+/* PR c++/24516 */
+/* { dg-do compile } */
+
+void
+bar (int *p)
+{
+  int m;
+#pragma omp parallel for
+  for (m = 0; m < 1000; ++m)
+    switch (p[m])
+      {
+      case 1:
+	p[m] = 2;
+	break;
+      default:
+	p[m] = 3;
+	break;
+      }
+}
--- gcc/testsuite/g++.dg/gomp/block-11.C.jj	2005-10-25 17:03:47.000000000 +0200
+++ gcc/testsuite/g++.dg/gomp/block-11.C	2005-10-25 17:03:03.000000000 +0200
@@ -0,0 +1,19 @@
+/* PR c++/24516 */
+/* { dg-do compile } */
+
+void
+bar (int *p)
+{
+  int m;
+#pragma omp parallel for
+  for (m = 0; m < 1000; ++m)
+    switch (p[m])
+      {
+      case 1:
+	p[m] = 2;
+	break;
+      default:
+	p[m] = 3;
+	break;
+      }
+}


	Jakub


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