Parsing __func__ as an id-expression matters to decltype.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 9fcce85473de842f9a18e4203378dfb8129629a1
Author: Jason Merrill <ja...@redhat.com>
Date:   Fri Nov 7 13:55:24 2014 -0600

    	* 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 e142f42..e1b320a 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -4502,39 +4502,9 @@ 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 -- 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);
-	  }
+	       __func__ are the names of variables.  */
+	  goto id_expression;
 
 	case RID_VA_ARG:
 	  {
@@ -4955,6 +4925,7 @@ 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);
@@ -4963,8 +4934,6 @@ 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);
@@ -5201,10 +5170,9 @@ cp_parser_unqualified_id (cp_parser* parser,
       }
 
     case CPP_KEYWORD:
-      if (token->keyword == RID_OPERATOR)
+      switch (token->keyword)
 	{
-	  tree id;
-
+	case RID_OPERATOR:
 	  /* This could be a template-id, so we try that first.  */
 	  cp_parser_parse_tentatively (parser);
 	  /* Try a template-id.  */
@@ -5234,6 +5202,16 @@ 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);
+	  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
new file mode 100644
index 0000000..65dd27a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/decltype-func.C
@@ -0,0 +1,6 @@
+// { 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 d6f3eb5..cb8fdae 100644
--- a/gcc/testsuite/g++.dg/other/error34.C
+++ b/gcc/testsuite/g++.dg/other/error34.C
@@ -4,3 +4,4 @@
 
 S () : str(__PRETTY_FUNCTION__) {}	// { dg-error "forbids declaration" "decl" }
 // { dg-error "only constructors" "constructor" { target *-*-* } 5 }
+// { dg-prune-output "__PRETTY_FUNCTION__" }

Reply via email to