Patchwork [C++] PR 50080

login
register
mail settings
Submitter Paolo Carlini
Date Oct. 15, 2012, 6:33 p.m.
Message ID <507C56FD.7070003@oracle.com>
Download mbox | patch
Permalink /patch/191625/
State New
Headers show

Comments

Paolo Carlini - Oct. 15, 2012, 6:33 p.m.
On 10/15/2012 07:30 PM, Jason Merrill wrote:
> Actually, let's keep the diagnostic when compiling with -pedantic in 
> 98 mode.
... too late! ;) So I prepared the below, I'm finishing testing it.

Thanks,
Paolo.

//////////////////
/cp
2012-10-15  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/50080 (again)
	* parser.c (cp_parser_optional_template_keyword): When -pedantic
	and C++98 mode restore pre-Core/468 behavior.

/testsuite
2012-10-15  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/50080 (again)
	* g++.dg/parse/tmpl-outside2.C: Tweak, error in C++98.
	* g++.dg/parse/tmpl-outside1.C: Likewise.
	* g++.dg/template/qualttp18.C: Likewise.
	* g++.old-deja/g++.pt/memtemp87.C: Likewise.
	* g++.old-deja/g++.pt/overload13.C: Likewise.
Jason Merrill - Oct. 15, 2012, 6:35 p.m.
On 10/15/2012 11:33 AM, Paolo Carlini wrote:
> +	  && pedantic && cxx_dialect == cxx98)
> +	{
> +	  cp_token *token = cp_lexer_peek_token (parser->lexer);
> +	  error_at (token->location,
> +		    "in C++98 %<template%> (as a disambiguator) is only "
> +		    "allowed within templates");

The diagnostic should be a pedwarn rather than an error.  OK with that 
change.

Jason

Patch

Index: cp/parser.c
===================================================================
--- cp/parser.c	(revision 192465)
+++ cp/parser.c	(working copy)
@@ -23252,9 +23252,29 @@  cp_parser_optional_template_keyword (cp_parser *pa
 {
   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
     {
-      /* Consume the `template' keyword.  */
-      cp_lexer_consume_token (parser->lexer);
-      return true;
+      /* In C++98 the `template' keyword can only be used within templates;
+	 outside templates the parser can always figure out what is a
+	 template and what is not.  In C++11,  per the resolution of DR 468,
+	 'template' is allowed in cases where it is not strictly necessary.  */
+      if (!processing_template_decl
+	  && pedantic && cxx_dialect == cxx98)
+	{
+	  cp_token *token = cp_lexer_peek_token (parser->lexer);
+	  error_at (token->location,
+		    "in C++98 %<template%> (as a disambiguator) is only "
+		    "allowed within templates");
+	  /* If this part of the token stream is rescanned, the same
+	     error message would be generated.  So, we purge the token
+	     from the stream.  */
+	  cp_lexer_purge_token (parser->lexer);
+	  return false;
+	}
+      else
+	{
+	  /* Consume the `template' keyword.  */
+	  cp_lexer_consume_token (parser->lexer);
+	  return true;
+	}
     }
   return false;
 }
Index: testsuite/g++.old-deja/g++.pt/overload13.C
===================================================================
--- testsuite/g++.old-deja/g++.pt/overload13.C	(revision 192465)
+++ testsuite/g++.old-deja/g++.pt/overload13.C	(working copy)
@@ -7,5 +7,5 @@  struct A {
 int main ()
 {
   A a;
-  return a.template f (0);
+  return a.template f (0); // { dg-error "template" "" { target c++98 } }
 }
Index: testsuite/g++.old-deja/g++.pt/memtemp87.C
===================================================================
--- testsuite/g++.old-deja/g++.pt/memtemp87.C	(revision 192465)
+++ testsuite/g++.old-deja/g++.pt/memtemp87.C	(working copy)
@@ -12,4 +12,4 @@  class Q {
 template<template<class> class>
 class Y {
 };
-Q::template X<int> x;
+Q::template X<int> x; // { dg-error "template" "" { target c++98 } }
Index: testsuite/g++.dg/parse/tmpl-outside1.C
===================================================================
--- testsuite/g++.dg/parse/tmpl-outside1.C	(revision 192465)
+++ testsuite/g++.dg/parse/tmpl-outside1.C	(working copy)
@@ -7,4 +7,4 @@  struct X
    template <int i> struct Y {};
 };
 
-typedef X::template Y<0> y;
+typedef X::template Y<0> y; // { dg-error "template|invalid" "" { target c++98 } }
Index: testsuite/g++.dg/parse/tmpl-outside2.C
===================================================================
--- testsuite/g++.dg/parse/tmpl-outside2.C	(revision 192465)
+++ testsuite/g++.dg/parse/tmpl-outside2.C	(working copy)
@@ -15,5 +15,5 @@  void test()
 
 int main()
 {
-  typename A<double>::template B<int> b;
+  typename A<double>::template B<int> b; // { dg-error "template|expected" "" { target c++98 } }
 }
Index: testsuite/g++.dg/template/qualttp18.C
===================================================================
--- testsuite/g++.dg/template/qualttp18.C	(revision 192465)
+++ testsuite/g++.dg/template/qualttp18.C	(working copy)
@@ -14,7 +14,7 @@  template <template <class> class TT> struct X
 
 struct C
 {
-	X<A::template B> x;
+	X<A::template B> x;  // { dg-error "template" "" { target c++98 } }
 };
 
 int main()