enum pragma_context { pragma_external, pragma_struct, pragma_param,
pragma_stmt, pragma_compound };
static bool c_parser_pragma (c_parser *, enum pragma_context, bool *);
-static void c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
+static bool c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *);
static void c_parser_omp_end_declare_target (c_parser *);
-static void c_parser_omp_declare (c_parser *, enum pragma_context);
+static bool c_parser_omp_declare (c_parser *, enum pragma_context);
static void c_parser_omp_requires (c_parser *);
static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
static void c_parser_oacc_routine (c_parser *, enum pragma_context);
if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE)
add_debug_begin_stmt (loc);
+ restart:
switch (c_parser_peek_token (parser)->type)
{
case CPP_OPEN_BRACE:
c_parser_consume_token (parser);
break;
case CPP_PRAGMA:
- c_parser_pragma (parser, pragma_stmt, if_p);
+ if (!c_parser_pragma (parser, pragma_stmt, if_p))
+ goto restart;
break;
default:
expr_stmt:
"%<#pragma %s%> may only be used in compound "
"statements", construct);
c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
- return false;
+ return true;
}
goto bad_stmt;
}
return false;
case PRAGMA_OMP_CANCELLATION_POINT:
- c_parser_omp_cancellation_point (parser, context);
- return false;
+ return c_parser_omp_cancellation_point (parser, context);
case PRAGMA_OMP_THREADPRIVATE:
c_parser_omp_threadprivate (parser);
return false;
case PRAGMA_OMP_DECLARE:
- c_parser_omp_declare (parser, context);
- return false;
+ return c_parser_omp_declare (parser, context);
case PRAGMA_OMP_REQUIRES:
if (context != pragma_external)
else
c_parser_do_statement (parser, ivdep, unroll);
}
- return false;
+ return true;
case PRAGMA_UNROLL:
{
else
c_parser_do_statement (parser, ivdep, unroll);
}
- return false;
+ return true;
case PRAGMA_GCC_PCH_PREPROCESS:
c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
"%<#pragma omp ordered%> with %<depend%> clause may "
"only be used in compound statements");
c_parser_skip_to_pragma_eol (parser, false);
- return false;
+ return true;
}
tree clauses
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
-static void
+static bool
c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context)
{
location_t loc = c_parser_peek_token (parser)->location;
{
c_parser_error (parser, "expected %<point%>");
c_parser_skip_to_pragma_eol (parser);
- return;
+ return false;
}
if (context != pragma_compound)
else
c_parser_error (parser, "expected declaration specifiers");
c_parser_skip_to_pragma_eol (parser, false);
- return;
+ return true;
}
clauses
"#pragma omp cancellation point");
c_finish_omp_cancellation_point (loc, clauses);
+ return true;
}
/* OpenMP 4.0:
error_at (loc, "%<#pragma %s%> may only be used in compound statements",
"omp target update");
c_parser_skip_to_pragma_eol (parser, false);
- return false;
+ return true;
}
tree clauses
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
-static tree
+static bool
c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
enum pragma_context context)
{
{
c_parser_error (parser, "expected %<data%>");
c_parser_skip_to_pragma_eol (parser);
- return NULL_TREE;
+ return false;
}
if (context == pragma_stmt)
error_at (loc, "%<#pragma %s%> may only be used in compound statements",
"omp target enter data");
c_parser_skip_to_pragma_eol (parser, false);
- return NULL_TREE;
+ return true;
}
tree clauses
error_at (loc,
"%<#pragma omp target enter data%> must contain at least "
"one %<map%> clause");
- return NULL_TREE;
+ return true;
}
tree stmt = make_node (OMP_TARGET_ENTER_DATA);
OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
SET_EXPR_LOCATION (stmt, loc);
add_stmt (stmt);
- return stmt;
+ return true;
}
/* OpenMP 4.5:
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
-static tree
+static bool
c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
enum pragma_context context)
{
{
c_parser_error (parser, "expected %<data%>");
c_parser_skip_to_pragma_eol (parser);
- return NULL_TREE;
+ return false;
}
if (context == pragma_stmt)
error_at (loc, "%<#pragma %s%> may only be used in compound statements",
"omp target exit data");
c_parser_skip_to_pragma_eol (parser, false);
- return NULL_TREE;
+ return true;
}
tree clauses
error_at (loc,
"%<#pragma omp target exit data%> must contain at least one "
"%<map%> clause");
- return NULL_TREE;
+ return true;
}
tree stmt = make_node (OMP_TARGET_EXIT_DATA);
OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
SET_EXPR_LOCATION (stmt, loc);
add_stmt (stmt);
- return stmt;
+ return true;
}
/* OpenMP 4.0:
else if (strcmp (p, "enter") == 0)
{
c_parser_consume_token (parser);
- c_parser_omp_target_enter_data (loc, parser, context);
- return false;
+ return c_parser_omp_target_enter_data (loc, parser, context);
}
else if (strcmp (p, "exit") == 0)
{
c_parser_consume_token (parser);
- c_parser_omp_target_exit_data (loc, parser, context);
- return false;
+ return c_parser_omp_target_exit_data (loc, parser, context);
}
else if (strcmp (p, "update") == 0)
{
OpenMP 5.0
#pragma omp declare variant (identifier) match (context-selector) */
-static void
+static bool
c_parser_omp_declare (c_parser *parser, enum pragma_context context)
{
c_parser_consume_pragma (parser);
/* c_parser_consume_token (parser); done in
c_parser_omp_declare_simd. */
c_parser_omp_declare_simd (parser, context);
- return;
+ return true;
}
if (strcmp (p, "reduction") == 0)
{
c_parser_consume_token (parser);
c_parser_omp_declare_reduction (parser, context);
- return;
+ return false;
}
if (!flag_openmp) /* flag_openmp_simd */
{
c_parser_skip_to_pragma_eol (parser, false);
- return;
+ return false;
}
if (strcmp (p, "target") == 0)
{
c_parser_consume_token (parser);
c_parser_omp_declare_target (parser);
- return;
+ return false;
}
if (strcmp (p, "variant") == 0)
{
/* c_parser_consume_token (parser); done in
c_parser_omp_declare_simd. */
c_parser_omp_declare_simd (parser, context);
- return;
+ return true;
}
}
c_parser_error (parser, "expected %<simd%>, %<reduction%>, "
"%<target%> or %<variant%>");
c_parser_skip_to_pragma_eol (parser);
+ return false;
}
/* OpenMP 5.0
"%<depend%> clause may only be used in compound "
"statements");
cp_parser_skip_to_pragma_eol (parser, pragma_tok);
- return false;
+ return true;
}
tree clauses
= cp_parser_omp_all_clauses (parser,
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
-static void
+static bool
cp_parser_omp_cancellation_point (cp_parser *parser, cp_token *pragma_tok,
enum pragma_context context)
{
{
cp_parser_error (parser, "expected %<point%>");
cp_parser_skip_to_pragma_eol (parser, pragma_tok);
- return;
+ return false;
}
if (context != pragma_compound)
else
cp_parser_error (parser, "expected declaration specifiers");
cp_parser_skip_to_pragma_eol (parser, pragma_tok);
- return;
+ return true;
}
clauses = cp_parser_omp_all_clauses (parser,
"#pragma omp cancellation point",
pragma_tok);
finish_omp_cancellation_point (clauses);
+ return true;
}
/* OpenMP 4.0:
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
-static tree
+static bool
cp_parser_omp_target_enter_data (cp_parser *parser, cp_token *pragma_tok,
enum pragma_context context)
{
{
cp_parser_error (parser, "expected %<data%>");
cp_parser_skip_to_pragma_eol (parser, pragma_tok);
- return NULL_TREE;
+ return false;
}
if (context == pragma_stmt)
"%<#pragma %s%> may only be used in compound statements",
"omp target enter data");
cp_parser_skip_to_pragma_eol (parser, pragma_tok);
- return NULL_TREE;
+ return true;
}
tree clauses
error_at (pragma_tok->location,
"%<#pragma omp target enter data%> must contain at least "
"one %<map%> clause");
- return NULL_TREE;
+ return true;
}
tree stmt = make_node (OMP_TARGET_ENTER_DATA);
TREE_TYPE (stmt) = void_type_node;
OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
SET_EXPR_LOCATION (stmt, pragma_tok->location);
- return add_stmt (stmt);
+ add_stmt (stmt);
+ return true;
}
/* OpenMP 4.5:
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
-static tree
+static bool
cp_parser_omp_target_exit_data (cp_parser *parser, cp_token *pragma_tok,
enum pragma_context context)
{
{
cp_parser_error (parser, "expected %<data%>");
cp_parser_skip_to_pragma_eol (parser, pragma_tok);
- return NULL_TREE;
+ return false;
}
if (context == pragma_stmt)
"%<#pragma %s%> may only be used in compound statements",
"omp target exit data");
cp_parser_skip_to_pragma_eol (parser, pragma_tok);
- return NULL_TREE;
+ return true;
}
tree clauses
error_at (pragma_tok->location,
"%<#pragma omp target exit data%> must contain at least "
"one %<map%> clause");
- return NULL_TREE;
+ return true;
}
tree stmt = make_node (OMP_TARGET_EXIT_DATA);
TREE_TYPE (stmt) = void_type_node;
OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
SET_EXPR_LOCATION (stmt, pragma_tok->location);
- return add_stmt (stmt);
+ add_stmt (stmt);
+ return true;
}
/* OpenMP 4.0:
"%<#pragma %s%> may only be used in compound statements",
"omp target update");
cp_parser_skip_to_pragma_eol (parser, pragma_tok);
- return false;
+ return true;
}
tree clauses
error_at (pragma_tok->location,
"%<#pragma omp target update%> must contain at least one "
"%<from%> or %<to%> clauses");
- return false;
+ return true;
}
tree stmt = make_node (OMP_TARGET_UPDATE);
OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
SET_EXPR_LOCATION (stmt, pragma_tok->location);
add_stmt (stmt);
- return false;
+ return true;
}
/* OpenMP 4.0:
else if (strcmp (p, "enter") == 0)
{
cp_lexer_consume_token (parser->lexer);
- cp_parser_omp_target_enter_data (parser, pragma_tok, context);
- return false;
+ return cp_parser_omp_target_enter_data (parser, pragma_tok, context);
}
else if (strcmp (p, "exit") == 0)
{
cp_lexer_consume_token (parser->lexer);
- cp_parser_omp_target_exit_data (parser, pragma_tok, context);
- return false;
+ return cp_parser_omp_target_exit_data (parser, pragma_tok, context);
}
else if (strcmp (p, "update") == 0)
{
cp_token *pragma_tok;
unsigned int id;
tree stmt;
- bool ret;
+ bool ret = false;
pragma_tok = cp_lexer_consume_token (parser->lexer);
gcc_assert (pragma_tok->type == CPP_PRAGMA);
case pragma_stmt:
error_at (pragma_tok->location, "%<#pragma %s%> may only be "
"used in compound statements", "omp barrier");
+ ret = true;
break;
default:
goto bad_stmt;
case pragma_stmt:
error_at (pragma_tok->location, "%<#pragma %s%> may only be "
"used in compound statements", "omp depobj");
+ ret = true;
break;
default:
goto bad_stmt;
case pragma_stmt:
error_at (pragma_tok->location, "%<#pragma %s%> may only be "
"used in compound statements", "omp flush");
+ ret = true;
break;
default:
goto bad_stmt;
error_at (pragma_tok->location,
"%<#pragma %s%> may only be used in compound statements",
"omp taskwait");
+ ret = true;
break;
default:
goto bad_stmt;
error_at (pragma_tok->location,
"%<#pragma %s%> may only be used in compound statements",
"omp taskyield");
+ ret = true;
break;
default:
goto bad_stmt;
error_at (pragma_tok->location,
"%<#pragma %s%> may only be used in compound statements",
"omp cancel");
+ ret = true;
break;
default:
goto bad_stmt;
break;
case PRAGMA_OMP_CANCELLATION_POINT:
- cp_parser_omp_cancellation_point (parser, pragma_tok, context);
- return false;
+ return cp_parser_omp_cancellation_point (parser, pragma_tok, context);
case PRAGMA_OMP_THREADPRIVATE:
cp_parser_omp_threadprivate (parser, pragma_tok);
error_at (pragma_tok->location,
"%<#pragma %s%> may only be used in compound statements",
"acc enter data");
+ ret = true;
break;
}
else if (context != pragma_compound)
error_at (pragma_tok->location,
"%<#pragma %s%> may only be used in compound statements",
"acc exit data");
+ ret = true;
break;
}
else if (context != pragma_compound)
{
error_at (pragma_tok->location,
"%<#pragma acc routine%> must be at file scope");
+ ret = true;
break;
}
cp_parser_oacc_routine (parser, pragma_tok, context);
error_at (pragma_tok->location,
"%<#pragma %s%> may only be used in compound statements",
"acc update");
+ ret = true;
break;
}
else if (context != pragma_compound)
error_at (pragma_tok->location,
"%<#pragma %s%> may only be used in compound statements",
"acc wait");
+ ret = true;
break;
}
else if (context != pragma_compound)
error_at (pragma_tok->location,
"%<#pragma omp requires%> may only be used at file or "
"namespace scope");
+ ret = true;
break;
}
return cp_parser_omp_requires (parser, pragma_tok);
}
cp_parser_skip_to_pragma_eol (parser, pragma_tok);
- return false;
+ return ret;
}
/* The interface the pragma parsers have to the lexer. */
{
do
#pragma omp barrier /* { dg-error "may only be used in compound statements" } */
- while (0); /* { dg-error "before" "" { target c++ } } */
- } /* { dg-error "before" "" { target c++ } } */
+ while (0);
+ }
{
do
#pragma omp flush /* { dg-error "may only be used in compound statements" } */
- while (0); /* { dg-error "before" "" { target c++ } } */
- } /* { dg-error "before" "" { target c++ } } */
+ while (0);
+ }
{
do
#pragma omp taskwait /* { dg-error "may only be used in compound statements" } */
- while (0); /* { dg-error "before" "" { target c++ } } */
- } /* { dg-error "before" "" { target c++ } } */
+ while (0);
+ }
{
do
#pragma omp taskyield /* { dg-error "may only be used in compound statements" } */
- while (0); /* { dg-error "before" "" { target c++ } } */
- } /* { dg-error "before" "" { target c++ } } */
+ while (0);
+ }
#pragma omp parallel
{
do
#pragma omp cancel parallel /* { dg-error "may only be used in compound statements" } */
- while (0); /* { dg-error "before" "" { target c++ } } */
- } /* { dg-error "before" "" { target c++ } } */
+ while (0);
+ }
#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++ } } */
- } /* { dg-error "before" "" { target c++ } } */
+ while (0);
+ }
#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++ } } */
- } /* { dg-error "before" "" { target c++ } } */
+ while (0);
+ }
{
do
#pragma omp ordered depend(sink: i-1) /* { dg-error "may only be used in compound statements" } */
- while (0); /* { dg-error "before" "" { target c++ } } */
- } /* { dg-error "before" "" { target c++ } } */
+ while (0);
+ }
}
{
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++ } } */
- } /* { dg-error "before" "" { target c++ } } */
+ while (0);
+ }
{
do
#pragma omp target update to(i) /* { dg-error "may only be used in compound statements" } */
- while (0); /* { dg-error "before" "" { target c++ } } */
- } /* { dg-error "before" "" { target c++ } } */
+ while (0);
+ }
{
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++ } } */
- } /* { dg-error "before" "" { target c++ } } */
+ while (0);
+ }
}
void
// { dg-error "#pragma omp section" "" { target *-*-* } .-1 }
// { dg-error "#pragma omp flush" "" { target *-*-* } .-2 }
[[omp::sequence (directive (flush), omp::directive (section))]]; // { dg-error "must be the only specified attribute on a statement" }
- // { dg-error "#pragma omp section" "" { target *-*-* } .-1 }
- // { dg-error "#pragma omp flush" "" { target *-*-* } .-2 }
+ // { dg-error "#pragma omp flush" "" { target *-*-* } .-1 }
[[gnu::cold, omp::directive (section)]]; // { dg-error "must be the only specified attribute on a statement" }
// { dg-error "#pragma omp section" "" { target *-*-* } .-1 }
[[omp::directive (section)]] [[gnu::cold]]; // { dg-error "must be the only specified attribute on a statement" }
{
if (p)
#pragma omp barrier // { dg-error "compound statements" }
-} // { dg-error "" }
+}
void f2(void)
{
- label: /* { dg-error "label at end of compound statement" } */
- /* { dg-warning "defined but not used" "" { target *-*-* } .-1 } */
+ label: /* { dg-warning "defined but not used" } */
#pragma omp barrier /* { dg-error "may only be used in compound statements" } */
}
lab:
#pragma omp declare simd simdlen (8) aligned (b : 8 * sizeof (int))
extern int f5 (int a, int *b, int c); /* { dg-error "must be followed by function declaration or definition" } */
- x++; /* { dg-error "a label can only be part of a statement and a declaration is not a statement" "" { target *-*-* } .-1 } */
+ x++;
}
return x;
}
lab:
#pragma omp declare variant (fn0) match (user={condition(0)})
extern int f5 (int a, int *b, int c); /* { dg-error "must be followed by function declaration or definition" } */
- x++; /* { dg-error "a label can only be part of a statement and a declaration is not a statement" "" { target *-*-* } .-1 } */
+ x++;
}
return x;
}