OSDN Git Service

2009-04-10 Manuel López-Ibáñez <manu@gcc.gnu.org>
authormanu <manu@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 10 Apr 2009 12:47:58 +0000 (12:47 +0000)
committermanu <manu@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 10 Apr 2009 12:47:58 +0000 (12:47 +0000)
PR  c++/20118
cp/
* parser.c (cp_parser_check_template_parameters): Take a
cp_declarator parameter.
(cp_parser_elaborated_type_specifier): Update to
cp_parser_check_template_parameters.
(cp_parser_class_head): Likewise.
(cp_parser_check_declarator_template_parameters): Likewise.
(cp_parser_check_template_parameters): Handle first the non-error
conditions. Give more accurate diagnostics if a declarator is
given.
testsuite/
* g++.dg/parse/pr20118.C: New.
* g++.dg/template/spec16.C: Update.

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

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

index b11e004..847b485 100644 (file)
@@ -1,3 +1,16 @@
+2009-04-10  Manuel López-Ibáñez  <manu@gcc.gnu.org>
+
+       PR  c++/20118
+       * parser.c (cp_parser_check_template_parameters): Take a
+       cp_declarator parameter.
+       (cp_parser_elaborated_type_specifier): Update to
+       cp_parser_check_template_parameters.
+       (cp_parser_class_head): Likewise.
+       (cp_parser_check_declarator_template_parameters): Likewise.
+       (cp_parser_check_template_parameters): Handle first the non-error
+       conditions. Give more accurate diagnostics if a declarator is
+       given. 
+
 2009-04-08  Jason Merrill  <jason@redhat.com>
 
        PR c++/25185
index 18d62cc..68c0ef4 100644 (file)
@@ -1913,7 +1913,7 @@ static tree cp_parser_maybe_treat_template_as_class
 static bool cp_parser_check_declarator_template_parameters
   (cp_parser *, cp_declarator *, location_t);
 static bool cp_parser_check_template_parameters
-  (cp_parser *, unsigned, location_t);
+  (cp_parser *, unsigned, location_t, cp_declarator *);
 static tree cp_parser_simple_cast_expression
   (cp_parser *);
 static tree cp_parser_global_scope_opt
@@ -11765,7 +11765,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
             there were no qualifying templates.  */
          if (!cp_parser_check_template_parameters (parser,
                                                    /*num_templates=*/0,
-                                                   token->location))
+                                                   token->location,
+                                                   /*declarator=*/NULL))
            return error_mark_node;
          type = xref_tag (tag_type, identifier, ts, template_p);
        }
@@ -15402,7 +15403,8 @@ cp_parser_class_head (cp_parser* parser,
   /* Make sure that the right number of template parameters were
      present.  */
   if (!cp_parser_check_template_parameters (parser, num_templates,
-                                           type_start_token->location))
+                                           type_start_token->location,
+                                           /*declarator=*/NULL))
     {
       /* If something went wrong, there is no point in even trying to
         process the class-definition.  */
@@ -17311,9 +17313,9 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
           additional level of template parameters.  */
        ++num_templates;
 
-      return cp_parser_check_template_parameters (parser,
-                                                 num_templates,
-                                                 declarator_location);
+      return cp_parser_check_template_parameters 
+       (parser, num_templates, declarator_location, declarator);
+
 
     case cdk_function:
     case cdk_array:
@@ -17334,30 +17336,38 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
 
 /* NUM_TEMPLATES were used in the current declaration.  If that is
    invalid, return FALSE and issue an error messages.  Otherwise,
-   return TRUE.  */
+   return TRUE.  If DECLARATOR is non-NULL, then we are checking a
+   declarator and we can print more accurate diagnostics.  */
 
 static bool
 cp_parser_check_template_parameters (cp_parser* parser,
                                     unsigned num_templates,
-                                    location_t location)
+                                    location_t location,
+                                    cp_declarator *declarator)
 {
+  /* If there are the same number of template classes and parameter
+     lists, that's OK.  */
+  if (parser->num_template_parameter_lists == num_templates)
+    return true;
+  /* If there are more, but only one more, then we are referring to a
+     member template.  That's OK too.  */
+  if (parser->num_template_parameter_lists == num_templates + 1)
+    return true;
   /* If there are more template classes than parameter lists, we have
      something like:
 
        template <class T> void S<T>::R<T>::f ();  */
   if (parser->num_template_parameter_lists < num_templates)
     {
-      error ("%Htoo few template-parameter-lists", &location);
+      if (declarator)
+       error_at (location, "specializing member %<%T::%E%> "
+                 "requires %<template<>%> syntax", 
+                 declarator->u.id.qualifying_scope,
+                 declarator->u.id.unqualified_name);
+      else 
+       error_at (location, "too few template-parameter-lists");
       return false;
     }
-  /* If there are the same number of template classes and parameter
-     lists, that's OK.  */
-  if (parser->num_template_parameter_lists == num_templates)
-    return true;
-  /* If there are more, but only one more, then we are referring to a
-     member template.  That's OK too.  */
-  if (parser->num_template_parameter_lists == num_templates + 1)
-      return true;
   /* Otherwise, there are too many template parameter lists.  We have
      something like:
 
index fdee1fa..d83fb5e 100644 (file)
@@ -1,3 +1,9 @@
+2009-04-10  Manuel López-Ibáñez  <manu@gcc.gnu.org>
+
+       PR  c++/20118
+       * g++.dg/parse/pr20118.C: New.
+       * g++.dg/template/spec16.C: Update.
+
 2009-04-09  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR testsuite/35621
        * gfortran.dg/typebound_proc_11.f03: New test.
        * gfortran.dg/abstract_type_5.f03: New test.
 
-2008-03-29  Tobias Schlüter  <tobi@gcc.gnu.org>
+2008-03-29  Tobias Schlüter  <tobi@gcc.gnu.org>
 
        PR fortran/38507
        * gfortran.dg/do_4.f: New.
diff --git a/gcc/testsuite/g++.dg/parse/pr20118.C b/gcc/testsuite/g++.dg/parse/pr20118.C
new file mode 100644 (file)
index 0000000..94e000a
--- /dev/null
@@ -0,0 +1,9 @@
+// { dg-do compile }
+// { dg-options "-fshow-column" } 
+template<typename t>struct foo {
+  static const int i; };
+
+const int foo<bool>::i = 5; // { dg-error "11:specializing member .foo<bool>::i. requires .template<>. syntax" }
+
+int main() { return 0; }
+
index 881d7a0..c872052 100644 (file)
@@ -7,5 +7,5 @@ struct A {
   template<int M> void B () ; 
 }; 
 
-void A<0>::B<0>() {    // { dg-error "parameter-lists" }
+void A<0>::B<0>() {    // { dg-error "specializing member 'A<0>::B<0>' requires 'template<>' syntax" }
 }