PR c++/71569 - decltype of template.
authorJason Merrill <jason@redhat.com>
Thu, 1 Mar 2018 19:40:36 +0000 (14:40 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 1 Mar 2018 19:40:36 +0000 (14:40 -0500)
* parser.c (cp_parser_decltype_expr): Handle missing template args.

From-SVN: r258110

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/g++.dg/cpp0x/decltype-33837.C
gcc/testsuite/g++.dg/cpp0x/decltype43.C
gcc/testsuite/g++.dg/cpp1y/var-templ59.C [new file with mode: 0644]

index acaabd0e19740612dc01c94594693f21088dac18..df5f48c845b78d8db0b07f720c21d09605d21fce 100644 (file)
@@ -1,3 +1,8 @@
+2018-03-01  Jason Merrill  <jason@redhat.com>
+
+       PR c++/71569 - decltype of template.
+       * parser.c (cp_parser_decltype_expr): Handle missing template args.
+
 2018-03-01  Marek Polacek  <polacek@redhat.com>
 
        PR c++/84596
index 359460cd4d8d633c9cb84e17c23c72e6a6d7054f..e1acb07d29ef5d84b4540a1037bfb612a1e7030a 100644 (file)
@@ -13983,6 +13983,10 @@ cp_parser_decltype_expr (cp_parser *parser,
        expr = cp_parser_lookup_name_simple (parser, expr,
                                             id_expr_start_token->location);
 
+      if (expr && TREE_CODE (expr) == TEMPLATE_DECL)
+       /* A template without args is not a complete id-expression.  */
+       expr = error_mark_node;
+
       if (expr
           && expr != error_mark_node
           && TREE_CODE (expr) != TYPE_DECL
@@ -14048,6 +14052,9 @@ cp_parser_decltype_expr (cp_parser *parser,
          expression.  */
       cp_parser_abort_tentative_parse (parser);
 
+      /* Commit to the tentative_firewall so we get syntax errors.  */
+      cp_parser_commit_to_tentative_parse (parser);
+
       /* Parse a full expression.  */
       expr = cp_parser_expression (parser, /*pidk=*/NULL, /*cast_p=*/false,
                                   /*decltype_p=*/true);
index fbbc6a14972aaa52cd5c65693d0bce610032e03f..4a8f053234eb79fd9a73815c6050ef3207ac2ade 100644 (file)
@@ -2,6 +2,6 @@
 // PR c++/33837
 void foo()
 {
-  __decltype (A::foo()); // { dg-error "was not declared|expected" }
-  __decltype (B); // { dg-error "was not declared" }
+  __decltype (A::foo()); // { dg-error "A" }
+  __decltype (B); // { dg-error "B" }
 }
index 4df95a1047c70f23a3db7b6506b2e6b1ac733dfb..7a1dcbf8744c120f2c303e9d072fe66ccc6eb1bc 100644 (file)
@@ -22,6 +22,6 @@ struct B
 int main()
 {
   int x = B<decltype(A<int>::a(1))>::b(A<int>::a(1));
-  int y = B<decltype(A     ::a(2))>::b(A<int>::a(2)); // { dg-error "template argument" }
+  int y = B<decltype(A     ::a(2))>::b(A<int>::a(2)); // { dg-error "template" }
   return x + y;
 }
diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ59.C b/gcc/testsuite/g++.dg/cpp1y/var-templ59.C
new file mode 100644 (file)
index 0000000..da9710e
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/71569
+// { dg-do compile { target c++14 } }
+
+template <class T>
+struct A {
+  template <class U>
+  static U u;
+};
+
+int main()
+{
+  decltype(A<int>::u) a;       // { dg-error "missing template arguments" }
+  return a;
+}