Hi! When parsing default arguments, we need to temporarily clear parser->omp_declare_simd and parser->oacc_routine, otherwise it can clash with further declarations inside of e.g. lambdas inside of those default arguments.
Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk, will backport eventually. 2021-08-04 Jakub Jelinek <ja...@redhat.com> PR c++/101759 * parser.c (cp_parser_default_argument): Temporarily override parser->omp_declare_simd and parser->oacc_routine to NULL. * g++.dg/gomp/pr101759.C: New test. * g++.dg/goacc/pr101759.C: New test. --- gcc/cp/parser.c.jj 2021-08-03 17:38:07.541725977 +0200 +++ gcc/cp/parser.c 2021-08-03 19:23:08.693843077 +0200 @@ -24509,6 +24509,8 @@ cp_parser_default_argument (cp_parser *p set correctly. */ saved_greater_than_is_operator_p = parser->greater_than_is_operator_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); /* Local variable names (and the `this' keyword) may not appear in a default argument. */ saved_local_variables_forbidden_p = parser->local_variables_forbidden_p; --- gcc/testsuite/g++.dg/gomp/pr101759.C.jj 2021-08-03 19:32:56.091725711 +0200 +++ gcc/testsuite/g++.dg/gomp/pr101759.C 2021-08-03 19:36:03.762138412 +0200 @@ -0,0 +1,8 @@ +// PR c++/101759 +// { dg-do compile { target c++11 } } + +#pragma omp declare simd +int foo (int x = []() { extern int bar (int); return 1; }()); +int corge (int = 1); +#pragma omp declare variant (corge) match (user={condition(true)}) +int baz (int x = []() { extern int qux (int); return 1; }()); --- gcc/testsuite/g++.dg/goacc/pr101759.C.jj 2021-08-03 19:33:15.079463941 +0200 +++ gcc/testsuite/g++.dg/goacc/pr101759.C 2021-08-03 19:35:53.148284738 +0200 @@ -0,0 +1,5 @@ +// PR c++/101759 +// { dg-do compile { target c++11 } } + +#pragma acc routine +int foo (int x = []() { extern int bar (int); return 1; }()); Jakub