PR c++/55639 - partial specialization with ::template
authorJason Merrill <jason@redhat.com>
Wed, 28 Jun 2017 19:41:49 +0000 (15:41 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 28 Jun 2017 19:41:49 +0000 (15:41 -0400)
* parser.c (cp_parser_class_head): Handle ::template.

From-SVN: r249754

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/g++.dg/template/partial-specialization8.C [new file with mode: 0644]

index 7b7070adf9c5ad9892d2d953448ba9d5d9619ee4..f4b93ca7d10007d20e547eb64f53d19446c270b8 100644 (file)
@@ -1,5 +1,8 @@
 2017-06-28  Jason Merrill  <jason@redhat.com>
 
+       PR c++/55639 - partial specialization with ::template
+       * parser.c (cp_parser_class_head): Handle ::template.
+
        PR c++/45976 - error with ::template in declarator.
        * pt.c (resolve_typename_type): Fix TEMPLATE_ID_EXPR handling.
 
index c9fc2844b7fa1cfd62ecf991231bd27160962a18..bd99c0513405d1ae72042d5e5d645545a8596c0d 100644 (file)
@@ -22602,6 +22602,9 @@ cp_parser_class_head (cp_parser* parser,
                                           /*is_declaration=*/false);
   /* If there was a nested-name-specifier, then there *must* be an
      identifier.  */
+
+  cp_token *bad_template_keyword = NULL;
+
   if (nested_name_specifier)
     {
       type_start_token = cp_lexer_peek_token (parser->lexer);
@@ -22623,6 +22626,8 @@ cp_parser_class_head (cp_parser* parser,
         class-name is a template-id; if we looked for the
         template-name first we would stop after the template-name.  */
       cp_parser_parse_tentatively (parser);
+      if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
+       bad_template_keyword = cp_lexer_consume_token (parser->lexer);
       type = cp_parser_class_name (parser,
                                   /*typename_keyword_p=*/false,
                                   /*template_keyword_p=*/false,
@@ -22742,6 +22747,12 @@ cp_parser_class_head (cp_parser* parser,
     {
       tree scope;
 
+      if (bad_template_keyword)
+       /* [temp.names]: in a qualified-id formed by a class-head-name, the
+          keyword template shall not appear at the top level.  */
+       pedwarn (bad_template_keyword->location, OPT_Wpedantic,
+                "keyword %<template%> not allowed in class-head-name");
+
       /* Reject typedef-names in class heads.  */
       if (!DECL_IMPLICIT_TYPEDEF_P (type))
        {
diff --git a/gcc/testsuite/g++.dg/template/partial-specialization8.C b/gcc/testsuite/g++.dg/template/partial-specialization8.C
new file mode 100644 (file)
index 0000000..e3ffe3b
--- /dev/null
@@ -0,0 +1,19 @@
+// PR c++/55639
+
+template <int number>
+struct SomeClass
+{
+  SomeClass() { }
+
+  template <typename E, int number2>
+  struct Fun {
+    static void
+    fun() { }
+  };
+};
+
+template <int number>
+template <typename E>
+struct SomeClass<number>::template Fun<E, 0> { // { dg-error "template" }
+  static void fun() { }
+};