If you try to use decltype(auto) in C++11, we emit obscure

  error: expected primary-expression before 'auto'

giving the user no hint as to what's wrong.  This patch improves that
diagnostic.  Since we've been giving an error, I'm also using error().

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

gcc/cp/ChangeLog:

        PR c++/96103
        * parser.c (cp_parser_decltype): Print error about using decltype(auto)
        in C++11.  Check that the token following "auto" is ")".

gcc/testsuite/ChangeLog:

        PR c++/96103
        * g++.dg/cpp0x/decltype77.C: New test.
---
 gcc/cp/parser.c                         | 22 +++++++++++++++-------
 gcc/testsuite/g++.dg/cpp0x/decltype77.C | 10 ++++++++++
 2 files changed, 25 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/decltype77.C

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index e58d8eb298c..8aaedaefb86 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -14894,11 +14894,11 @@ cp_parser_decltype_expr (cp_parser *parser,
   return expr;
 }
 
-/* Parse a `decltype' type. Returns the type.
+/* Parse a `decltype' type.  Returns the type.
 
-   simple-type-specifier:
+   decltype-specifier:
      decltype ( expression )
-   C++14 proposal:
+   C++14:
      decltype ( auto )  */
 
 static tree
@@ -14938,10 +14938,18 @@ cp_parser_decltype (cp_parser *parser)
 
   tree expr = NULL_TREE;
 
-  if (cxx_dialect >= cxx14
-      && cp_lexer_next_token_is_keyword (parser->lexer, RID_AUTO))
-    /* decltype (auto) */
-    cp_lexer_consume_token (parser->lexer);
+  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AUTO)
+      && cp_lexer_nth_token_is (parser->lexer, 2, CPP_CLOSE_PAREN))
+    {
+      /* decltype (auto) */
+      cp_lexer_consume_token (parser->lexer);
+      if (cxx_dialect < cxx14)
+       {
+         error_at (start_token->location,
+                   "%<decltype(auto)%> type specifier is a C++14 extension");
+         expr = error_mark_node;
+       }
+    }
   else
     {
       /* decltype (expression)  */
diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype77.C 
b/gcc/testsuite/g++.dg/cpp0x/decltype77.C
new file mode 100644
index 00000000000..1f987118510
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/decltype77.C
@@ -0,0 +1,10 @@
+// PR c++/96103
+// { dg-do compile { target c++11_only } }
+
+decltype(auto) foo () { return 4; } // { dg-error ".decltype\\(auto\\). type 
specifier is a C\\+\\+14 extension" }
+
+void
+bar ()
+{
+  decltype(auto) i = 0; // { dg-error ".decltype\\(auto\\). type specifier is 
a C\\+\\+14 extension" }
+}

base-commit: 7126583af5d29235584b51b3b05eeaba2adef024
-- 
2.26.2

Reply via email to