c++: Better diagnostic for decltype(auto) in C++11 [PR96103]
authorMarek Polacek <polacek@redhat.com>
Tue, 7 Jul 2020 21:09:42 +0000 (17:09 -0400)
committerMarek Polacek <polacek@redhat.com>
Wed, 8 Jul 2020 13:13:39 +0000 (09:13 -0400)
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().

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
gcc/testsuite/g++.dg/cpp0x/decltype77.C [new file with mode: 0644]

index e58d8eb298c0eedb74d6e0023a0f58cb6f1e769d..528b41b717096b07590174003b8a9eeb760f500c 100644 (file)
@@ -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,19 @@ 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 only available with "
+                   "%<-std=c++14%> or %<-std=gnu++14%>");
+         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 (file)
index 0000000..ffd59d4
--- /dev/null
@@ -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 only available" }
+
+void
+bar ()
+{
+  decltype(auto) i = 0; // { dg-error ".decltype\\(auto\\). type specifier only available" }
+}