On Fri, Jan 4, 2013 at 9:41 AM, Xinliang David Li <davi...@google.com> wrote: > ok.
The patch as sent caused some breakage, I had to adjust test cases a bit. Submitting attached patch. Thanks, -- Paul Pluzhnikov
Index: gcc/testsuite/g++.old-deja/g++.other/crash28.C =================================================================== --- gcc/testsuite/g++.old-deja/g++.other/crash28.C (revision 194909) +++ gcc/testsuite/g++.old-deja/g++.other/crash28.C (working copy) @@ -31,5 +31,5 @@ }; 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: gcc/testsuite/g++.dg/parse/error12.C =================================================================== --- gcc/testsuite/g++.dg/parse/error12.C (revision 194909) +++ gcc/testsuite/g++.dg/parse/error12.C (working copy) @@ -8,6 +8,6 @@ template <class A> struct Foo {}; -Foo<::B> foo; // { dg-bogus "error" "error in place of warning" } -// { dg-warning "4: '<::' cannot begin a template-argument list" "warning <::" { target *-*-* } 11 } -// { dg-message "4:'<:' is an alternate spelling for '.'. Insert whitespace between '<' and '::'" "note <:" { target *-*-* } 11 } +Foo<::B> foo; // { dg-bogus "error" "error in place of warning" { target c++98 } } +// { dg-warning "4: '<::' cannot begin a template-argument list" "warning <::" { target c++98 } 11 } +// { dg-message "4:'<:' is an alternate spelling for '.'. Insert whitespace between '<' and '::'" "note <:" { target c++98 } 11 } Index: gcc/testsuite/g++.dg/parse/error11.C =================================================================== --- gcc/testsuite/g++.dg/parse/error11.C (revision 194909) +++ gcc/testsuite/g++.dg/parse/error11.C (working copy) @@ -16,22 +16,22 @@ }; void method(void) { - typename Foo<::B>::template Nested<::B> n; // { dg-error "17:'<::' cannot begin" "17-begin" } -// { dg-message "17:'<:' is an alternate spelling" "17-alt" { target *-*-* } 19 } -// { dg-error "39:'<::' cannot begin" "39-begin" { target *-*-* } 19 } -// { dg-message "39:'<:' is an alternate spelling" "39-alt" { target *-*-* } 19 } + typename Foo<::B>::template Nested<::B> n; // { dg-error "17:'<::' cannot begin" "17-begin" { target c++98 } } +// { dg-message "17:'<:' is an alternate spelling" "17-alt" { target c++98 } 19 } +// { dg-error "39:'<::' cannot begin" "39-begin" { target c++98 } 19 } +// { dg-message "39:'<:' is an alternate spelling" "39-alt" { target c++98 } 19 } n.template Nested<B>::method(); - n.template Nested<::B>::method(); // { dg-error "22:'<::' cannot begin" "error" } -// { dg-message "22:'<:' is an alternate" "note" { target *-*-* } 24 } + n.template Nested<::B>::method(); // { dg-error "22:'<::' cannot begin" "error" { target c++98 } } +// { dg-message "22:'<:' is an alternate" "note" { target c++98 } 24 } Nested<B>::method(); - Nested<::B>::method(); // { dg-error "11:'<::' cannot begin" "error" } -// { dg-message "11:'<:' is an alternate" "note" { target *-*-* } 27 } + Nested<::B>::method(); // { dg-error "11:'<::' cannot begin" "error" { target c++98 } } +// { dg-message "11:'<:' is an alternate" "note" { target c++98 } 27 } } }; template <int N> struct Foo2 {}; -template struct Foo2<::B>; // { dg-error "21:'<::' cannot begin" "begin" } -// { dg-message "21:'<:' is an alternate" "alt" { target *-*-* } 33 } +template struct Foo2<::B>; // { dg-error "21:'<::' cannot begin" "begin" { target c++98 } } +// { dg-message "21:'<:' is an alternate" "alt" { target c++98 } 33 } // { dg-message "25:type/value mismatch" "mismatch" { target *-*-* } 33 } // { dg-error "25:expected a constant" "const" { target *-*-* } 33 } @@ -39,11 +39,11 @@ void func(void) { - Foo<::B> f; // { dg-error "cannot begin" "begin" } -// { dg-message "alternate spelling" "alt" { target *-*-* } 42 } + Foo<::B> f; // { dg-error "cannot begin" "begin" { target c++98 } } +// { dg-message "alternate spelling" "alt" { target c++98 } 42 } f.Foo<B>::method(); - f.Foo<::B>::method(); // { dg-error "8:cannot begin" "begin" } -// { dg-message "8:alternate spelling" "alt" { target *-*-* } 45 } + f.Foo<::B>::method(); // { dg-error "8:cannot begin" "begin" { target c++98 } } +// { dg-message "8:alternate spelling" "alt" { target c++98 } 45 } // Check cases where we the token sequence is the correct one, but there // was no digraph or whitespaces in the middle, so we should not emit @@ -63,9 +63,9 @@ Foo[::value] = 0; } -template struct Foo<::B>; // { dg-error "20:'<::' cannot begin" "begin" } -// { dg-message "20:is an alternate" "alt" { target *-*-* } 66 } +template struct Foo<::B>; // { dg-error "20:'<::' cannot begin" "begin" { target c++98 } } +// { dg-message "20:is an alternate" "alt" { target c++98 } 66 } // On the first error message, an additional note about the use of // -fpermissive should be present -// { dg-message "17:\\(if you use '-fpermissive' G\\+\\+ will accept your code\\)" "-fpermissive" { target *-*-* } 19 } +// { dg-message "17:\\(if you use '-fpermissive' G\\+\\+ will accept your code\\)" "-fpermissive" { target c++98 } 19 } Index: libcpp/lex.c =================================================================== --- libcpp/lex.c (revision 194909) +++ libcpp/lex.c (working copy) @@ -2224,6 +2224,17 @@ { if (*buffer->cur == ':') { + /* C++11 [2.5/3 lex.pptoken], "Otherwise, if the next + three characters are <:: and the subsequent character + is neither : nor >, the < is treated as a preprocessor + token by itself". */ + 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++; result->flags |= DIGRAPH; result->type = CPP_OPEN_SQUARE;