It seems that my strict reading of the standard conflicts with existing
practice in a way that is not useful. So I'm reverting my earlier patch.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 9dfef51ff302e644acf0111685a7451867049959
Author: Jason Merrill <ja...@redhat.com>
Date: Wed Dec 10 17:33:19 2014 -0500
PR c++/64248
Revert:
* parser.c (cp_parser_unqualified_id): Handle __func__ here.
(cp_parser_primary_expression): Not here.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 48dd64a..76725ef 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -4503,9 +4503,39 @@ cp_parser_primary_expression (cp_parser *parser,
case RID_FUNCTION_NAME:
case RID_PRETTY_FUNCTION_NAME:
case RID_C99_FUNCTION_NAME:
+ {
+ non_integral_constant name;
+
/* The symbols __FUNCTION__, __PRETTY_FUNCTION__, and
- __func__ are the names of variables. */
- goto id_expression;
+ __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 = NIC_FUNC_NAME;
+ break;
+ case RID_PRETTY_FUNCTION_NAME:
+ name = NIC_PRETTY_FUNC;
+ break;
+ case RID_C99_FUNCTION_NAME:
+ name = NIC_C99_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:
{
@@ -4926,7 +4956,6 @@ cp_parser_unqualified_id (cp_parser* parser,
bool optional_p)
{
cp_token *token;
- tree id;
/* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);
@@ -4935,6 +4964,8 @@ cp_parser_unqualified_id (cp_parser* parser,
{
case CPP_NAME:
{
+ tree id;
+
/* We don't know yet whether or not this will be a
template-id. */
cp_parser_parse_tentatively (parser);
@@ -5171,9 +5202,10 @@ cp_parser_unqualified_id (cp_parser* parser,
}
case CPP_KEYWORD:
- switch (token->keyword)
+ if (token->keyword == RID_OPERATOR)
{
- case RID_OPERATOR:
+ tree id;
+
/* This could be a template-id, so we try that first. */
cp_parser_parse_tentatively (parser);
/* Try a template-id. */
@@ -5203,19 +5235,6 @@ cp_parser_unqualified_id (cp_parser* parser,
}
return id;
-
- case RID_FUNCTION_NAME:
- case RID_PRETTY_FUNCTION_NAME:
- case RID_C99_FUNCTION_NAME:
- cp_lexer_consume_token (parser->lexer);
- /* Don't try to declare this while tentatively parsing a function
- declarator, as cp_make_fname_decl will fail. */
- if (current_binding_level->kind != sk_function_parms)
- finish_fname (token->u.value);
- return token->u.value;
-
- default:
- break;
}
/* Fall through. */
diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype-func.C b/gcc/testsuite/g++.dg/cpp0x/decltype-func.C
deleted file mode 100644
index 65dd27a..0000000
--- a/gcc/testsuite/g++.dg/cpp0x/decltype-func.C
+++ /dev/null
@@ -1,6 +0,0 @@
-// { dg-do compile { target c++11 } }
-
-void f() {
- typedef decltype(__func__) T;
- T x = __func__; // { dg-error "array" }
-}
diff --git a/gcc/testsuite/g++.dg/other/error34.C b/gcc/testsuite/g++.dg/other/error34.C
index cb8fdae..d6f3eb5 100644
--- a/gcc/testsuite/g++.dg/other/error34.C
+++ b/gcc/testsuite/g++.dg/other/error34.C
@@ -4,4 +4,3 @@
S () : str(__PRETTY_FUNCTION__) {} // { dg-error "forbids declaration" "decl" }
// { dg-error "only constructors" "constructor" { target *-*-* } 5 }
-// { dg-prune-output "__PRETTY_FUNCTION__" }
diff --git a/gcc/testsuite/g++.dg/parse/fnname2.C b/gcc/testsuite/g++.dg/parse/fnname2.C
new file mode 100644
index 0000000..7fc0f82
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/fnname2.C
@@ -0,0 +1,19 @@
+// PR c++/64248
+
+class A
+{
+public:
+ A(const char* str) {};
+};
+
+class B
+{
+public:
+ B(A a) {};
+};
+
+int main()
+{
+ B b(A(__func__));
+ return 0;
+}