Fix PR c++/61537
authorabutcher <abutcher@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 26 Jun 2014 05:12:52 +0000 (05:12 +0000)
committerabutcher <abutcher@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 26 Jun 2014 05:12:52 +0000 (05:12 +0000)
* parser.c (cp_parser_elaborated_type_specifier): Only consider template
parameter lists outside of function parameter scope.

* g++.dg/template/pr61537.C: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@212008 138bc75d-0d04-0410-961f-82ee72b054a4

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

index c3d520e..124f4d6 100644 (file)
@@ -1,3 +1,9 @@
+2014-06-26  Adam Butcher  <adam@jessamine.co.uk>
+
+       PR c++/61537
+       * parser.c (cp_parser_elaborated_type_specifier): Only consider template
+       parameter lists outside of function parameter scope.
+
 2014-06-25  Paolo Carlini  <paolo.carlini@oracle.com>
 
        DR 178
index 41200a0..c440c99 100644 (file)
@@ -15081,6 +15081,18 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
        return cp_parser_make_typename_type (parser, parser->scope,
                                             identifier,
                                             token->location);
+
+      /* Template parameter lists apply only if we are not within a
+        function parameter list.  */
+      bool template_parm_lists_apply
+         = parser->num_template_parameter_lists;
+      if (template_parm_lists_apply)
+       for (cp_binding_level *s = current_binding_level;
+            s && s->kind != sk_template_parms;
+            s = s->level_chain)
+         if (s->kind == sk_function_parms)
+           template_parm_lists_apply = false;
+
       /* Look up a qualified name in the usual way.  */
       if (parser->scope)
        {
@@ -15123,7 +15135,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
 
          decl = (cp_parser_maybe_treat_template_as_class
                  (decl, /*tag_name_p=*/is_friend
-                        && parser->num_template_parameter_lists));
+                        && template_parm_lists_apply));
 
          if (TREE_CODE (decl) != TYPE_DECL)
            {
@@ -15136,9 +15148,9 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
 
          if (TREE_CODE (TREE_TYPE (decl)) != TYPENAME_TYPE)
             {
-              bool allow_template = (parser->num_template_parameter_lists
-                                     || DECL_SELF_REFERENCE_P (decl));
-              type = check_elaborated_type_specifier (tag_type, decl, 
+              bool allow_template = (template_parm_lists_apply
+                                    || DECL_SELF_REFERENCE_P (decl));
+              type = check_elaborated_type_specifier (tag_type, decl,
                                                       allow_template);
 
               if (type == error_mark_node)
@@ -15224,15 +15236,16 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
            ts = ts_global;
 
          template_p =
-           (parser->num_template_parameter_lists
+           (template_parm_lists_apply
             && (cp_parser_next_token_starts_class_definition_p (parser)
                 || cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)));
          /* An unqualified name was used to reference this type, so
             there were no qualifying templates.  */
-         if (!cp_parser_check_template_parameters (parser,
-                                                   /*num_templates=*/0,
-                                                   token->location,
-                                                   /*declarator=*/NULL))
+         if (template_parm_lists_apply
+             && !cp_parser_check_template_parameters (parser,
+                                                      /*num_templates=*/0,
+                                                      token->location,
+                                                      /*declarator=*/NULL))
            return error_mark_node;
          type = xref_tag (tag_type, identifier, ts, template_p);
        }
index d88cb7f..d10b03b 100644 (file)
@@ -1,3 +1,8 @@
+2014-06-26  Adam Butcher  <adam@jessamine.co.uk>
+
+       PR c++/61537
+       * g++.dg/template/pr61537.C: New testcase.
+
 2014-06-25  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
 
        * gfortran.dg/default_format_denormal_2.f90:  Remove xfail for
diff --git a/gcc/testsuite/g++.dg/template/pr61537.C b/gcc/testsuite/g++.dg/template/pr61537.C
new file mode 100644 (file)
index 0000000..12aaf58
--- /dev/null
@@ -0,0 +1,23 @@
+// PR c++/61537
+// { dg-do compile }
+
+struct A {};
+
+template <typename T>
+struct B
+{
+  template <typename U>
+  void f(U, struct A);
+};
+
+template <typename T>
+template <typename U>
+void B<T>::f(U, struct A)
+{
+}
+
+int main()
+{
+  B<char> b;
+  b.f(42, A());
+}