public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* PR c++/20118 missing template<> causes weird errors
@ 2008-08-12 15:30 Manuel López-Ibáñez
  2008-08-25  8:16 ` Manuel López-Ibáñez
  0 siblings, 1 reply; 6+ messages in thread
From: Manuel López-Ibáñez @ 2008-08-12 15:30 UTC (permalink / raw)
  To: Gcc Patch List

[-- Attachment #1: Type: text/plain, Size: 735 bytes --]

Bootstrapped and regression tested on x86_64-unknown-linux-gnu with
--enable-languages=all,ada

OK for trunk?

2008-08-12  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>

	PR  c++/20118
	* diagnostic.c (error_at): New.
	* toplev.h (error_at): Declare.
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.

[-- Attachment #2: fix-pr20118.diff --]
[-- Type: text/plain, Size: 7352 bytes --]

Index: gcc/diagnostic.c
===================================================================
--- gcc/diagnostic.c	(revision 138904)
+++ gcc/diagnostic.c	(working copy)
@@ -599,12 +599,27 @@ permerror (const char *gmsgid, ...)
   va_end (ap);
   return report_diagnostic (&diagnostic);
 }
 
 
-/* A hard error: the code is definitely ill-formed, and an object file
-   will not be produced.  */
+/* A hard error at LOCATION: the code is definitely ill-formed, and an
+   object file will not be produced.  */
+
+void
+error_at (location_t location, const char *gmsgid, ...)
+{
+  diagnostic_info diagnostic;
+  va_list ap;
+
+  va_start (ap, gmsgid);
+  diagnostic_set_info (&diagnostic, gmsgid, &ap, location, DK_ERROR);
+  report_diagnostic (&diagnostic);
+  va_end (ap);
+}
+
+/* Equivalent to error_at (input_location, ...).  */
+
 void
 error (const char *gmsgid, ...)
 {
   diagnostic_info diagnostic;
   va_list ap;
Index: gcc/toplev.h
===================================================================
--- gcc/toplev.h	(revision 138904)
+++ gcc/toplev.h	(working copy)
@@ -59,10 +59,12 @@ extern void internal_error (const char *
 /* Pass one of the OPT_W* from options.h as the first parameter.  */
 extern bool warning (int, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
 extern bool warning_at (location_t, int, const char *, ...)
     ATTRIBUTE_GCC_DIAG(3,4);
 extern void error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
+extern void error_at (location_t, const char *, ...)
+     ATTRIBUTE_GCC_DIAG(2,3);
 extern void fatal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2)
      ATTRIBUTE_NORETURN;
 /* Pass one of the OPT_W* from options.h as the first parameter.  */
 extern bool pedwarn (int, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
 extern bool permerror (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
Index: gcc/testsuite/g++.dg/parse/pr20118.C
===================================================================
--- gcc/testsuite/g++.dg/parse/pr20118.C	(revision 0)
+++ gcc/testsuite/g++.dg/parse/pr20118.C	(revision 0)
@@ -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: error: specializing member .foo<bool>::i. requires .template<>. syntax" }
+
+int main() { return 0; }
+
Index: gcc/testsuite/g++.dg/template/spec16.C
===================================================================
--- gcc/testsuite/g++.dg/template/spec16.C	(revision 138904)
+++ gcc/testsuite/g++.dg/template/spec16.C	(working copy)
@@ -5,7 +5,7 @@
 template <int N>  
 struct A { 
   template<int M> void B () ; 
 }; 
 
-void A<0>::B<0>() {    // { dg-error "parameter-lists" }
+void A<0>::B<0>() {    // { dg-error "error: specializing member 'A<0>::B<0>' requires 'template<>' syntax" }
 } 
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 138904)
+++ gcc/cp/parser.c	(working copy)
@@ -1905,11 +1905,11 @@ static tree cp_parser_lookup_name_simple
 static tree cp_parser_maybe_treat_template_as_class
   (tree, bool);
 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
   (cp_parser *, bool);
 static bool cp_parser_constructor_declarator_p
@@ -11591,11 +11591,12 @@ cp_parser_elaborated_type_specifier (cp_
 		 || 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))
+						    token->location,
+						    /*declarator=*/NULL))
 	    return error_mark_node;
 	  type = xref_tag (tag_type, identifier, ts, template_p);
 	}
     }
 
@@ -15049,11 +15050,12 @@ cp_parser_class_head (cp_parser* parser,
      end of this function; set "type "to the correct return value and
      use "goto done;" to return.  */
   /* 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.  */
       type = NULL_TREE;
       goto done;
@@ -16946,13 +16948,13 @@ cp_parser_check_declarator_template_para
 	       == TEMPLATE_ID_EXPR)
 	/* If the DECLARATOR has the form `X<y>' then it uses one
 	   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:
     case cdk_pointer:
     case cdk_reference:
@@ -16969,34 +16971,42 @@ cp_parser_check_declarator_template_para
   return false;
 }
 
 /* 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:
 
      template <class T> template <class U> void S::f();  */
   error ("%Htoo many template-parameter-lists", &location);

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PR c++/20118 missing template<> causes weird errors
  2008-08-12 15:30 PR c++/20118 missing template<> causes weird errors Manuel López-Ibáñez
@ 2008-08-25  8:16 ` Manuel López-Ibáñez
  2008-10-20 16:49   ` Manuel López-Ibáñez
  0 siblings, 1 reply; 6+ messages in thread
From: Manuel López-Ibáñez @ 2008-08-25  8:16 UTC (permalink / raw)
  To: Gcc Patch List

[-- Attachment #1: Type: text/plain, Size: 1009 bytes --]

PING: http://gcc.gnu.org/ml/gcc-patches/2008-08/msg00793.html

2008/8/12 Manuel López-Ibáñez <lopezibanez@gmail.com>:
> Bootstrapped and regression tested on x86_64-unknown-linux-gnu with
> --enable-languages=all,ada
>
> OK for trunk?
>
> 2008-08-12  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
>
>        PR  c++/20118
>        * diagnostic.c (error_at): New.
>        * toplev.h (error_at): Declare.
> 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.
>

[-- Attachment #2: fix-pr20118.diff --]
[-- Type: text/plain, Size: 7352 bytes --]

Index: gcc/diagnostic.c
===================================================================
--- gcc/diagnostic.c	(revision 138904)
+++ gcc/diagnostic.c	(working copy)
@@ -599,12 +599,27 @@ permerror (const char *gmsgid, ...)
   va_end (ap);
   return report_diagnostic (&diagnostic);
 }
 
 
-/* A hard error: the code is definitely ill-formed, and an object file
-   will not be produced.  */
+/* A hard error at LOCATION: the code is definitely ill-formed, and an
+   object file will not be produced.  */
+
+void
+error_at (location_t location, const char *gmsgid, ...)
+{
+  diagnostic_info diagnostic;
+  va_list ap;
+
+  va_start (ap, gmsgid);
+  diagnostic_set_info (&diagnostic, gmsgid, &ap, location, DK_ERROR);
+  report_diagnostic (&diagnostic);
+  va_end (ap);
+}
+
+/* Equivalent to error_at (input_location, ...).  */
+
 void
 error (const char *gmsgid, ...)
 {
   diagnostic_info diagnostic;
   va_list ap;
Index: gcc/toplev.h
===================================================================
--- gcc/toplev.h	(revision 138904)
+++ gcc/toplev.h	(working copy)
@@ -59,10 +59,12 @@ extern void internal_error (const char *
 /* Pass one of the OPT_W* from options.h as the first parameter.  */
 extern bool warning (int, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
 extern bool warning_at (location_t, int, const char *, ...)
     ATTRIBUTE_GCC_DIAG(3,4);
 extern void error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
+extern void error_at (location_t, const char *, ...)
+     ATTRIBUTE_GCC_DIAG(2,3);
 extern void fatal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2)
      ATTRIBUTE_NORETURN;
 /* Pass one of the OPT_W* from options.h as the first parameter.  */
 extern bool pedwarn (int, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
 extern bool permerror (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
Index: gcc/testsuite/g++.dg/parse/pr20118.C
===================================================================
--- gcc/testsuite/g++.dg/parse/pr20118.C	(revision 0)
+++ gcc/testsuite/g++.dg/parse/pr20118.C	(revision 0)
@@ -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: error: specializing member .foo<bool>::i. requires .template<>. syntax" }
+
+int main() { return 0; }
+
Index: gcc/testsuite/g++.dg/template/spec16.C
===================================================================
--- gcc/testsuite/g++.dg/template/spec16.C	(revision 138904)
+++ gcc/testsuite/g++.dg/template/spec16.C	(working copy)
@@ -5,7 +5,7 @@
 template <int N>  
 struct A { 
   template<int M> void B () ; 
 }; 
 
-void A<0>::B<0>() {    // { dg-error "parameter-lists" }
+void A<0>::B<0>() {    // { dg-error "error: specializing member 'A<0>::B<0>' requires 'template<>' syntax" }
 } 
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 138904)
+++ gcc/cp/parser.c	(working copy)
@@ -1905,11 +1905,11 @@ static tree cp_parser_lookup_name_simple
 static tree cp_parser_maybe_treat_template_as_class
   (tree, bool);
 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
   (cp_parser *, bool);
 static bool cp_parser_constructor_declarator_p
@@ -11591,11 +11591,12 @@ cp_parser_elaborated_type_specifier (cp_
 		 || 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))
+						    token->location,
+						    /*declarator=*/NULL))
 	    return error_mark_node;
 	  type = xref_tag (tag_type, identifier, ts, template_p);
 	}
     }
 
@@ -15049,11 +15050,12 @@ cp_parser_class_head (cp_parser* parser,
      end of this function; set "type "to the correct return value and
      use "goto done;" to return.  */
   /* 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.  */
       type = NULL_TREE;
       goto done;
@@ -16946,13 +16948,13 @@ cp_parser_check_declarator_template_para
 	       == TEMPLATE_ID_EXPR)
 	/* If the DECLARATOR has the form `X<y>' then it uses one
 	   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:
     case cdk_pointer:
     case cdk_reference:
@@ -16969,34 +16971,42 @@ cp_parser_check_declarator_template_para
   return false;
 }
 
 /* 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:
 
      template <class T> template <class U> void S::f();  */
   error ("%Htoo many template-parameter-lists", &location);

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PR c++/20118 missing template<> causes weird errors
  2008-08-25  8:16 ` Manuel López-Ibáñez
@ 2008-10-20 16:49   ` Manuel López-Ibáñez
  2008-10-29 19:26     ` Manuel López-Ibáñez
  0 siblings, 1 reply; 6+ messages in thread
From: Manuel López-Ibáñez @ 2008-10-20 16:49 UTC (permalink / raw)
  To: Gcc Patch List

[-- Attachment #1: Type: text/plain, Size: 1218 bytes --]

I have updated the patch to a recent revision, bootstrapped and
regression tested again.

OK for trunk?

Manuel.

2008/8/25 Manuel López-Ibáñez <lopezibanez@gmail.com>:
> PING: http://gcc.gnu.org/ml/gcc-patches/2008-08/msg00793.html
>
> 2008/8/12 Manuel López-Ibáñez <lopezibanez@gmail.com>:
>> Bootstrapped and regression tested on x86_64-unknown-linux-gnu with
>> --enable-languages=all,ada
>>
>> OK for trunk?
>>
>> 2008-08-12  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
>>
>>        PR  c++/20118
>>        * diagnostic.c (error_at): New.
>>        * toplev.h (error_at): Declare.
>> 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.
>>
>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: fix-pr20118.diff --]
[-- Type: text/x-diff; name=fix-pr20118.diff, Size: 5515 bytes --]

Index: gcc/testsuite/g++.dg/parse/pr20118.C
===================================================================
--- gcc/testsuite/g++.dg/parse/pr20118.C	(revision 0)
+++ gcc/testsuite/g++.dg/parse/pr20118.C	(revision 0)
@@ -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: gcc/testsuite/g++.dg/template/spec16.C
===================================================================
--- gcc/testsuite/g++.dg/template/spec16.C	(revision 141233)
+++ gcc/testsuite/g++.dg/template/spec16.C	(working copy)
@@ -5,7 +5,7 @@
 template <int N>  
 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" }
 } 
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 141233)
+++ gcc/cp/parser.c	(working copy)
@@ -1909,11 +1909,11 @@ static tree cp_parser_lookup_name_simple
 static tree cp_parser_maybe_treat_template_as_class
   (tree, bool);
 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
   (cp_parser *, bool);
 static bool cp_parser_constructor_declarator_p
@@ -11651,11 +11651,12 @@ cp_parser_elaborated_type_specifier (cp_
 		 || 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))
+						    token->location,
+						    /*declarator=*/NULL))
 	    return error_mark_node;
 	  type = xref_tag (tag_type, identifier, ts, template_p);
 	}
     }
 
@@ -15241,11 +15242,12 @@ cp_parser_class_head (cp_parser* parser,
      end of this function; set "type "to the correct return value and
      use "goto done;" to return.  */
   /* 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.  */
       type = NULL_TREE;
       goto done;
@@ -17140,13 +17142,13 @@ cp_parser_check_declarator_template_para
 	       == TEMPLATE_ID_EXPR)
 	/* If the DECLARATOR has the form `X<y>' then it uses one
 	   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:
     case cdk_pointer:
     case cdk_reference:
@@ -17163,34 +17165,42 @@ cp_parser_check_declarator_template_para
   return false;
 }
 
 /* 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:
 
      template <class T> template <class U> void S::f();  */
   error ("%Htoo many template-parameter-lists", &location);

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PR c++/20118 missing template<> causes weird errors
  2008-10-20 16:49   ` Manuel López-Ibáñez
@ 2008-10-29 19:26     ` Manuel López-Ibáñez
  2008-12-06  0:25       ` Mark Mitchell
  0 siblings, 1 reply; 6+ messages in thread
From: Manuel López-Ibáñez @ 2008-10-29 19:26 UTC (permalink / raw)
  To: Gcc Patch List

[-- Attachment #1: Type: text/plain, Size: 1384 bytes --]

PING: http://gcc.gnu.org/ml/gcc-patches/2008-10/msg00807.html

2008/10/20 Manuel López-Ibáñez <lopezibanez@gmail.com>:
> I have updated the patch to a recent revision, bootstrapped and
> regression tested again.
>
> OK for trunk?
>
> Manuel.
>
> 2008/8/25 Manuel López-Ibáñez <lopezibanez@gmail.com>:
>> PING: http://gcc.gnu.org/ml/gcc-patches/2008-08/msg00793.html
>>
>> 2008/8/12 Manuel López-Ibáñez <lopezibanez@gmail.com>:
>>> Bootstrapped and regression tested on x86_64-unknown-linux-gnu with
>>> --enable-languages=all,ada
>>>
>>> OK for trunk?
>>>
>>> 2008-08-12  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
>>>
>>>        PR  c++/20118
>>>        * diagnostic.c (error_at): New.
>>>        * toplev.h (error_at): Declare.
>>> 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.
>>>
>>
>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: fix-pr20118.diff --]
[-- Type: text/x-diff; name=fix-pr20118.diff, Size: 5515 bytes --]

Index: gcc/testsuite/g++.dg/parse/pr20118.C
===================================================================
--- gcc/testsuite/g++.dg/parse/pr20118.C	(revision 0)
+++ gcc/testsuite/g++.dg/parse/pr20118.C	(revision 0)
@@ -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: gcc/testsuite/g++.dg/template/spec16.C
===================================================================
--- gcc/testsuite/g++.dg/template/spec16.C	(revision 141233)
+++ gcc/testsuite/g++.dg/template/spec16.C	(working copy)
@@ -5,7 +5,7 @@
 template <int N>  
 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" }
 } 
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 141233)
+++ gcc/cp/parser.c	(working copy)
@@ -1909,11 +1909,11 @@ static tree cp_parser_lookup_name_simple
 static tree cp_parser_maybe_treat_template_as_class
   (tree, bool);
 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
   (cp_parser *, bool);
 static bool cp_parser_constructor_declarator_p
@@ -11651,11 +11651,12 @@ cp_parser_elaborated_type_specifier (cp_
 		 || 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))
+						    token->location,
+						    /*declarator=*/NULL))
 	    return error_mark_node;
 	  type = xref_tag (tag_type, identifier, ts, template_p);
 	}
     }
 
@@ -15241,11 +15242,12 @@ cp_parser_class_head (cp_parser* parser,
      end of this function; set "type "to the correct return value and
      use "goto done;" to return.  */
   /* 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.  */
       type = NULL_TREE;
       goto done;
@@ -17140,13 +17142,13 @@ cp_parser_check_declarator_template_para
 	       == TEMPLATE_ID_EXPR)
 	/* If the DECLARATOR has the form `X<y>' then it uses one
 	   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:
     case cdk_pointer:
     case cdk_reference:
@@ -17163,34 +17165,42 @@ cp_parser_check_declarator_template_para
   return false;
 }
 
 /* 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:
 
      template <class T> template <class U> void S::f();  */
   error ("%Htoo many template-parameter-lists", &location);

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PR c++/20118 missing template<> causes weird errors
  2008-10-29 19:26     ` Manuel López-Ibáñez
@ 2008-12-06  0:25       ` Mark Mitchell
  2009-04-10 12:48         ` Manuel López-Ibáñez
  0 siblings, 1 reply; 6+ messages in thread
From: Mark Mitchell @ 2008-12-06  0:25 UTC (permalink / raw)
  To: Manuel López-Ibáñez; +Cc: Gcc Patch List

Manuel López-Ibáñez wrote:

>>>> 2008-08-12  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
>>>>
>>>>        PR  c++/20118
>>>>        * diagnostic.c (error_at): New.
>>>>        * toplev.h (error_at): Declare.
>>>> 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.

OK.

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PR c++/20118 missing template<> causes weird errors
  2008-12-06  0:25       ` Mark Mitchell
@ 2009-04-10 12:48         ` Manuel López-Ibáñez
  0 siblings, 0 replies; 6+ messages in thread
From: Manuel López-Ibáñez @ 2009-04-10 12:48 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Gcc Patch List

[-- Attachment #1: Type: text/plain, Size: 1667 bytes --]

This was approved by Mark. I have committed it as revision 145892.

2009-04-10  Manuel López-Ibáñez  <manu@gcc.gnu.org>

	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.


2008/12/6 Mark Mitchell <mark@codesourcery.com>:
> Manuel López-Ibáñez wrote:
>
>>>>> 2008-08-12  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
>>>>>
>>>>>        PR  c++/20118
>>>>>        * diagnostic.c (error_at): New.
>>>>>        * toplev.h (error_at): Declare.
>>>>> 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.
>
> OK.
>
> --
> Mark Mitchell
> CodeSourcery
> mark@codesourcery.com
> (650) 331-3385 x713
>

[-- Attachment #2: fix-pr20118.diff --]
[-- Type: text/plain, Size: 5515 bytes --]

Index: gcc/testsuite/g++.dg/parse/pr20118.C
===================================================================
--- gcc/testsuite/g++.dg/parse/pr20118.C	(revision 0)
+++ gcc/testsuite/g++.dg/parse/pr20118.C	(revision 0)
@@ -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: gcc/testsuite/g++.dg/template/spec16.C
===================================================================
--- gcc/testsuite/g++.dg/template/spec16.C	(revision 145853)
+++ gcc/testsuite/g++.dg/template/spec16.C	(working copy)
@@ -5,7 +5,7 @@
 template <int N>  
 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" }
 } 
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 145853)
+++ gcc/cp/parser.c	(working copy)
@@ -1911,11 +1911,11 @@ static tree cp_parser_lookup_name_simple
 static tree cp_parser_maybe_treat_template_as_class
   (tree, bool);
 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
   (cp_parser *, bool);
 static bool cp_parser_constructor_declarator_p
@@ -11763,11 +11763,12 @@ cp_parser_elaborated_type_specifier (cp_
 		 || 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))
+						    token->location,
+						    /*declarator=*/NULL))
 	    return error_mark_node;
 	  type = xref_tag (tag_type, identifier, ts, template_p);
 	}
     }
 
@@ -15400,11 +15401,12 @@ cp_parser_class_head (cp_parser* parser,
      end of this function; set "type "to the correct return value and
      use "goto done;" to return.  */
   /* 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.  */
       type = NULL_TREE;
       goto done;
@@ -17309,13 +17311,13 @@ cp_parser_check_declarator_template_para
 	       == TEMPLATE_ID_EXPR)
 	/* If the DECLARATOR has the form `X<y>' then it uses one
 	   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:
     case cdk_pointer:
     case cdk_reference:
@@ -17332,34 +17334,42 @@ cp_parser_check_declarator_template_para
   return false;
 }
 
 /* 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:
 
      template <class T> template <class U> void S::f();  */
   error ("%Htoo many template-parameter-lists", &location);

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2009-04-10 12:48 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-08-12 15:30 PR c++/20118 missing template<> causes weird errors Manuel López-Ibáñez
2008-08-25  8:16 ` Manuel López-Ibáñez
2008-10-20 16:49   ` Manuel López-Ibáñez
2008-10-29 19:26     ` Manuel López-Ibáñez
2008-12-06  0:25       ` Mark Mitchell
2009-04-10 12:48         ` Manuel López-Ibáñez

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).