diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/parser.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/gomp/attrs-11.C | 12 |
2 files changed, 27 insertions, 0 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index ec885d7..fbb8130 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -11628,6 +11628,9 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr) middle of an expression. */ ++function_depth; + auto odsd = make_temp_override (parser->omp_declare_simd, NULL); + auto ord = make_temp_override (parser->oacc_routine, NULL); + auto oafp = make_temp_override (parser->omp_attrs_forbidden_p, false); vec<tree> omp_privatization_save; save_omp_privatization_clauses (omp_privatization_save); /* Clear this in case we're in the middle of a default argument. */ @@ -12271,9 +12274,11 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr, so let's un-parse them. */ saved_tokens.rollback(); + parser->omp_attrs_forbidden_p = omp_attrs_forbidden_p; cp_parser_parse_tentatively (parser); /* Try to parse the declaration-statement. */ cp_parser_declaration_statement (parser); + parser->omp_attrs_forbidden_p = false; /* If that worked, we're done. */ if (cp_parser_parse_definitely (parser)) return; @@ -24768,6 +24773,8 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p) parser->greater_than_is_operator_p = !template_parm_p; auto odsd = make_temp_override (parser->omp_declare_simd, NULL); auto ord = make_temp_override (parser->oacc_routine, NULL); + auto oafp = make_temp_override (parser->omp_attrs_forbidden_p, false); + /* Local variable names (and the `this' keyword) may not appear in a default argument. */ saved_local_variables_forbidden_p = parser->local_variables_forbidden_p; @@ -44503,6 +44510,14 @@ cp_parser_late_parsing_omp_declare_simd (cp_parser *parser, tree attrs) continue; } + if (parser->omp_attrs_forbidden_p) + { + error_at (first->location, + "mixing OpenMP directives with attribute and " + "pragma syntax on the same statement"); + parser->omp_attrs_forbidden_p = false; + } + if (!flag_openmp && strcmp (directive[1], "simd") != 0) continue; if (lexer == NULL) diff --git a/gcc/testsuite/g++.dg/gomp/attrs-11.C b/gcc/testsuite/g++.dg/gomp/attrs-11.C index 009bcb2..44e025e 100644 --- a/gcc/testsuite/g++.dg/gomp/attrs-11.C +++ b/gcc/testsuite/g++.dg/gomp/attrs-11.C @@ -72,3 +72,15 @@ int f28 [[omp::directive (declare simd), omp::directive (foobar)]] (int); // { d int f29 [[omp::directive (foobar), omp::directive (declare simd)]] (int); // { dg-error "unknown OpenMP directive name" } int f30 [[omp::directive (threadprivate (t7)), omp::directive (declare simd)]] (int); // { dg-error "OpenMP directive other than 'declare simd' or 'declare variant' appertains to a declaration" } int f31 [[omp::directive (declare simd), omp::directive (threadprivate (t8))]] (int); // { dg-error "OpenMP directive other than 'declare simd' or 'declare variant' appertains to a declaration" } + +void +baz () +{ + #pragma omp parallel + [[omp::directive (declare simd)]] extern int f32 (int); // { dg-error "mixing OpenMP directives with attribute and pragma syntax on the same statement" } + #pragma omp parallel + extern int f33 [[omp::directive (declare simd)]] (int); // { dg-error "mixing OpenMP directives with attribute and pragma syntax on the same statement" } + [[omp::directive (parallel)]] + #pragma omp declare simd // { dg-error "mixing OpenMP directives with attribute and pragma syntax on the same statement" } + extern int f34 (int); +} |