This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[gomp] Fix C++ break in switch inside of #pragma omp for (PR c++/24516)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Henderson <rth at redhat dot com>, Diego Novillo <dnovillo at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Tue, 25 Oct 2005 11:37:16 -0400
- Subject: [gomp] Fix C++ break in switch inside of #pragma omp for (PR c++/24516)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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