diff mbox

[C++] PR 54526 (again)

Message ID 508D16AC.5070901@oracle.com
State New
Headers show

Commit Message

Paolo Carlini Oct. 28, 2012, 11:27 a.m. UTC
Hi,

as pointed out in the audit trail, my first patch for this C++11 parsing 
issue was misguided: I changed cp_parser_template_id but in fact C++11 
wants new special *lexing* rules, which must be active outside templates 
too, as the additional test (and the old manded one) shows. Thus the below.

Tested x86_64-linux.

Thanks,
Paolo.

////////////////////////
/libcpp
2012-10-28  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/54526 (again)
	* lex.c (_cpp_lex_direct): In C++11 mode, implement 2.5 p3, bullet 2.

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

	PR c++/54526 (again)
	* parser.c (cp_parser_template_id): Revert core of previous change
	(keep adjusted inform message).

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

	PR c++/54526 (again)
	* g++.dg/cpp0x/parse2.C: Extend.
	* g++.old-deja/g++.other/crash28.C: Adjust.

Comments

Jakub Jelinek Jan. 2, 2013, 10:07 a.m. UTC | #1
Hi!

On Sun, Oct 28, 2012 at 12:27:40PM +0100, Paolo Carlini wrote:
> --- gcc/cp/parser.c	(revision 192887)
> +++ gcc/cp/parser.c	(working copy)
> @@ -12655,9 +12655,8 @@ cp_parser_template_id (cp_parser *parser,
>        /* Otherwise, emit an error about the invalid digraph, but continue
>  	 parsing because we got our argument list.  In C++11 do not emit
>  	 any error, per 2.5/3.  */

Shouldn't the "In C++11 do not emit"... sentence be removed from the comment
as well?

> -      if (cxx_dialect < cxx0x
> -	  && permerror (next_token->location,
> -			"%<<::%> cannot begin a template-argument list"))
> +      if (permerror (next_token->location,
> +		     "%<<::%> cannot begin a template-argument list"))
>  	{
>  	  static bool hint = false;
>  	  inform (next_token->location,

> --- libcpp/lex.c	(revision 192887)
> +++ libcpp/lex.c	(working copy)
> @@ -2291,6 +2291,25 @@ _cpp_lex_direct (cpp_reader *pfile)
>  	  if (*buffer->cur == ':')
>  	    {
>  	      buffer->cur++;
> +
> +	      /* C++11 - 2.5 p3, bullet 2.  */
> +	      if (CPP_OPTION (pfile, cplusplus)
> +		  && (CPP_OPTION (pfile, lang) == CLK_CXX11
> +		      || CPP_OPTION (pfile, lang) == CLK_GNUCXX11))
> +		{
> +		  if (*buffer->cur == ':')
> +		    {
> +		      buffer->cur++;
> +		      if (*buffer->cur != ':' && *buffer->cur != '>')
> +			{
> +			  --buffer->cur;
> +			  --buffer->cur;
> +			  break;
> +			}
> +		      --buffer->cur;

I'd say way too many ++/-- above.  I'd write it as:

- 	      buffer->cur++;
+
+	      /* C++11 - 2.5 p3, bullet 2.  */
+	      if (CPP_OPTION (pfile, cplusplus)
+		  && (CPP_OPTION (pfile, lang) == CLK_CXX11
+		      || CPP_OPTION (pfile, lang) == CLK_GNUCXX11)
+		  && buffer->cur[1] == ':'
+		  && buffer->cur[2] != ':' && buffer->cur[2] != '>')
+		break;
+
+	      buffer->cur++;

	Jakub
diff mbox

Patch

Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 192887)
+++ gcc/cp/parser.c	(working copy)
@@ -12655,9 +12655,8 @@  cp_parser_template_id (cp_parser *parser,
       /* Otherwise, emit an error about the invalid digraph, but continue
 	 parsing because we got our argument list.  In C++11 do not emit
 	 any error, per 2.5/3.  */
-      if (cxx_dialect < cxx0x
-	  && permerror (next_token->location,
-			"%<<::%> cannot begin a template-argument list"))
+      if (permerror (next_token->location,
+		     "%<<::%> cannot begin a template-argument list"))
 	{
 	  static bool hint = false;
 	  inform (next_token->location,
Index: gcc/testsuite/g++.dg/cpp0x/parse2.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/parse2.C	(revision 192887)
+++ gcc/testsuite/g++.dg/cpp0x/parse2.C	(working copy)
@@ -10,3 +10,6 @@  int main()
 {
   X<::A> x;
 }
+
+int a;
+bool b = 0<::a;
Index: gcc/testsuite/g++.old-deja/g++.other/crash28.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.other/crash28.C	(revision 192887)
+++ gcc/testsuite/g++.old-deja/g++.other/crash28.C	(working copy)
@@ -31,5 +31,5 @@  class foo
 };
 void foo::x() throw(bar)
 {
-  if (!b) throw bar (static_cast<::N::X*>(this));	// { dg-error "lambda expressions|expected" } parse error
+  if (!b) throw bar (static_cast<::N::X*>(this));	// { dg-error "lambda expressions|expected|invalid" } parse error
 }
Index: libcpp/lex.c
===================================================================
--- libcpp/lex.c	(revision 192887)
+++ libcpp/lex.c	(working copy)
@@ -2291,6 +2291,25 @@  _cpp_lex_direct (cpp_reader *pfile)
 	  if (*buffer->cur == ':')
 	    {
 	      buffer->cur++;
+
+	      /* C++11 - 2.5 p3, bullet 2.  */
+	      if (CPP_OPTION (pfile, cplusplus)
+		  && (CPP_OPTION (pfile, lang) == CLK_CXX11
+		      || CPP_OPTION (pfile, lang) == CLK_GNUCXX11))
+		{
+		  if (*buffer->cur == ':')
+		    {
+		      buffer->cur++;
+		      if (*buffer->cur != ':' && *buffer->cur != '>')
+			{
+			  --buffer->cur;
+			  --buffer->cur;
+			  break;
+			}
+		      --buffer->cur;
+		    }
+		}
+
 	      result->flags |= DIGRAPH;
 	      result->type = CPP_OPEN_SQUARE;
 	    }