From patchwork Sun Oct 28 11:27:40 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [C++] PR 54526 (again) Date: Sun, 28 Oct 2012 01:27:40 -0000 From: Paolo Carlini X-Patchwork-Id: 194690 Message-Id: <508D16AC.5070901@oracle.com> To: "gcc-patches@gcc.gnu.org" Cc: Jason Merrill 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 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 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 PR c++/54526 (again) * g++.dg/cpp0x/parse2.C: Extend. * g++.old-deja/g++.other/crash28.C: Adjust. 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; }