From: David Majnemer Date: Mon, 29 Dec 2014 23:12:23 +0000 (+0000) Subject: Parse: Recover more gracefully from extra :: tokens before a { X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4566372e6a80f624caa03dd9d230db6b7e62d45e;p=clang Parse: Recover more gracefully from extra :: tokens before a { Instead of crashing, recover by eating the extra trailing scope qualifier. This means we will treat 'struct A:: {' as 'struct A {'. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@224966 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index 55f9245d58..a6162e2d4c 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -442,7 +442,17 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, Next.setKind(tok::coloncolon); } } - + + if (Next.is(tok::coloncolon) && GetLookAheadToken(2).is(tok::l_brace)) { + // It is invalid to have :: {, consume the scope qualifier and pretend + // like we never saw it. + Token Identifier = Tok; // Stash away the identifier. + ConsumeToken(); // Eat the identifier, current token is now '::'. + Diag(PP.getLocForEndOfTokenConsumeToken(), diag::err_expected) << tok::identifier; + UnconsumeToken(Identifier); // Stick the identifier back. + Next = NextToken(); // Point Next at the '{' token. + } + if (Next.is(tok::coloncolon)) { if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde) && !Actions.isNonTypeNestedNameSpecifier( diff --git a/test/CXX/dcl.decl/dcl.meaning/p1.cpp b/test/CXX/dcl.decl/dcl.meaning/p1.cpp index 349f0d7058..cefee7b8dc 100644 --- a/test/CXX/dcl.decl/dcl.meaning/p1.cpp +++ b/test/CXX/dcl.decl/dcl.meaning/p1.cpp @@ -27,6 +27,7 @@ namespace NS { struct X; template struct Y; template void wibble(T); + struct Z; } namespace NS { // Under DR482, these are all valid, except for forward-declaring a struct @@ -45,3 +46,4 @@ namespace NS { } struct ::{} a; // expected-error{{expected identifier}} +struct NS::Z:: {} b; // expected-error{{expected identifier}}