Hi! In C++, the OpenMP variable lists are lists of id-expressions, which include template-ids; for those cp_parser_lookup_name_simple ICEs though, so this patch just calls that for identifiers similarly to other cp_parser_lookup_name_simple callers.
Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk so far. 2018-02-26 Jakub Jelinek <ja...@redhat.com> PR c++/84557 * parser.c (cp_parser_omp_var_list_no_open): Only call cp_parser_lookup_name_simple on names satisfying identifier_p. (cp_parser_oacc_routine): Likewise. * g++.dg/gomp/pr84557.C: New test. --- gcc/cp/parser.c.jj 2018-02-22 14:35:34.194215675 +0100 +++ gcc/cp/parser.c 2018-02-26 13:03:56.398478515 +0100 @@ -31339,7 +31339,10 @@ cp_parser_omp_var_list_no_open (cp_parse if (name == error_mark_node) goto skip_comma; - decl = cp_parser_lookup_name_simple (parser, name, token->location); + if (identifier_p (name)) + decl = cp_parser_lookup_name_simple (parser, name, token->location); + else + decl = name; if (decl == error_mark_node) cp_parser_name_lookup_error (parser, name, decl, NLE_NULL, token->location); @@ -37843,7 +37846,9 @@ cp_parser_oacc_routine (cp_parser *parse /*template_p=*/NULL, /*declarator_p=*/false, /*optional_p=*/false); - tree decl = cp_parser_lookup_name_simple (parser, name, name_loc); + tree decl = (identifier_p (name) + ? cp_parser_lookup_name_simple (parser, name, name_loc) + : name); if (name != error_mark_node && decl == error_mark_node) cp_parser_name_lookup_error (parser, name, decl, NLE_NULL, name_loc); --- gcc/testsuite/g++.dg/gomp/pr84557.C.jj 2018-02-26 13:04:34.074472152 +0100 +++ gcc/testsuite/g++.dg/gomp/pr84557.C 2018-02-26 13:04:17.014475036 +0100 @@ -0,0 +1,14 @@ +// PR c++/84557 +// { dg-do compile } + +template<int> struct A {}; +template<int> struct B {}; + +void +foo () +{ + #pragma omp parallel firstprivate (A) // { dg-error "is not a variable in clause" } + ; + #pragma omp parallel firstprivate (B<0>) // { dg-error "is not a variable in clause" } + ; +} Jakub