case RID_FUNCTION_NAME:
case RID_PRETTY_FUNCTION_NAME:
case RID_C99_FUNCTION_NAME:
- /* The symbols __FUNCTION__, __PRETTY_FUNCTION__, and
- __func__ are the names of variables -- but they are
- treated specially. Therefore, they are handled here,
- rather than relying on the generic id-expression logic
- below. Grammatically, these names are id-expressions.
+ {
+ const char *name;
- Consume the token. */
- token = cp_lexer_consume_token (parser->lexer);
- /* Look up the name. */
- return finish_fname (token->u.value);
+ /* The symbols __FUNCTION__, __PRETTY_FUNCTION__, and
+ __func__ are the names of variables -- but they are
+ treated specially. Therefore, they are handled here,
+ rather than relying on the generic id-expression logic
+ below. Grammatically, these names are id-expressions.
+
+ Consume the token. */
+ token = cp_lexer_consume_token (parser->lexer);
+
+ switch (token->keyword)
+ {
+ case RID_FUNCTION_NAME:
+ name = "%<__FUNCTION__%>";
+ break;
+ case RID_PRETTY_FUNCTION_NAME:
+ name = "%<__PRETTY_FUNCTION__%>";
+ break;
+ case RID_C99_FUNCTION_NAME:
+ name = "%<__func__%>";
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ if (cp_parser_non_integral_constant_expression (parser, name))
+ return error_mark_node;
+
+ /* Look up the name. */
+ return finish_fname (token->u.value);
+ }
case RID_VA_ARG:
{
--- /dev/null
+// PR c++/38647
+// { dg-do compile }
+
+template<const char *, int> struct A {};
+const char func[] = "abc";
+template<int N> struct A<func, N> {}; // { dg-error "cannot appear|is invalid" }
+
+char a1[1];
+A<a1, 0> a;
+
+template<const char *, int> struct B {};
+template<int N> struct B<__FUNCTION__, N> {}; // { dg-error "cannot appear|is invalid" }
+
+char b1[1];
+B<b1, 0> b;
+
+template<const char *, int> struct C {};
+template<int N> struct C<__PRETTY_FUNCTION__, N> {}; // { dg-error "cannot appear|is invalid" }
+
+char c1[1];
+C<c1, 0> c;
+
+template<const char *, int> struct D {};
+template<int N> struct D<__func__, N> {}; // { dg-error "cannot appear|is invalid" }
+
+char d1[1];
+D<d1, 0> d;