At the risk of seeming overly eager, I thought it would be reasonable to go with the following: enabling braced-init-list as a template-argument. As the discussion on the reflector clearly indicates, this was the intent from the get-go.
I know, it's not a regression. But I restricted the change to C++20, and it should strictly allow code that wasn't accepted before -- when a template argument starts with {. Perhaps we could even drop the C++20 check. What's your preference? Bootstrapped/regtested on x86_64-linux, ok for trunk? 2019-01-07 Marek Polacek <pola...@redhat.com> PR c++/88538 - braced-init-list in template-argument-list. * parser.c (cp_parser_template_argument): Handle braced-init-list when in C++20. * g++.dg/cpp2a/nontype-class11.C: New test. diff --git gcc/cp/parser.c gcc/cp/parser.c index bca1739ace3..7de2ee28b20 100644 --- gcc/cp/parser.c +++ gcc/cp/parser.c @@ -16892,7 +16892,18 @@ cp_parser_template_argument (cp_parser* parser) return argument; } /* It must be a non-type argument. In C++17 any constant-expression is - allowed. */ + allowed. In C++20, we can encounter a braced-init-list. */ + if (cxx_dialect >= cxx2a + && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) + { + cp_parser_parse_tentatively (parser); + bool expr_non_constant_p; + argument = cp_parser_braced_list (parser, &expr_non_constant_p); + if (cp_parser_parse_definitely (parser)) + /* Yup, it was a braced-init-list. */ + return argument; + } + if (cxx_dialect > cxx14) goto general_expr; diff --git gcc/testsuite/g++.dg/cpp2a/nontype-class11.C gcc/testsuite/g++.dg/cpp2a/nontype-class11.C new file mode 100644 index 00000000000..8a06d23904b --- /dev/null +++ gcc/testsuite/g++.dg/cpp2a/nontype-class11.C @@ -0,0 +1,21 @@ +// PR c++/88538 +// { dg-do compile { target c++2a } } + +struct S { + unsigned a; + unsigned b; + constexpr S(unsigned _a, unsigned _b) noexcept: a{_a}, b{_b} { } +}; + +template <S p> +void fnc() +{ +} + +template<S s> struct X { }; + +void f() +{ + fnc<{10,20}>(); + X<{1, 2}> x; +}