forked from OSchip/llvm-project
Parse: Consume tokens more carefully in CheckForLParenAfterColonColon
We would consume the lparen even if it wasn't followed by an identifier or a star-identifier pair. This fixes PR21815. llvm-svn: 224403
This commit is contained in:
parent
fc2201e922
commit
6ca445e0dd
|
@ -108,35 +108,37 @@ void Parser::CheckForLParenAfterColonColon() {
|
|||
if (!Tok.is(tok::l_paren))
|
||||
return;
|
||||
|
||||
SourceLocation l_parenLoc = ConsumeParen(), r_parenLoc;
|
||||
Token Tok1 = getCurToken();
|
||||
if (!Tok1.is(tok::identifier) && !Tok1.is(tok::star))
|
||||
Token LParen = Tok;
|
||||
Token NextTok = GetLookAheadToken(1);
|
||||
Token StarTok = NextTok;
|
||||
// Check for (identifier or (*identifier
|
||||
Token IdentifierTok = StarTok.is(tok::star) ? GetLookAheadToken(2) : StarTok;
|
||||
if (IdentifierTok.isNot(tok::identifier))
|
||||
return;
|
||||
|
||||
if (Tok1.is(tok::identifier)) {
|
||||
Token Tok2 = GetLookAheadToken(1);
|
||||
if (Tok2.is(tok::r_paren)) {
|
||||
// Eat the '('.
|
||||
ConsumeParen();
|
||||
Token RParen;
|
||||
// Do we have a ')' ?
|
||||
NextTok = StarTok.is(tok::star) ? GetLookAheadToken(2) : GetLookAheadToken(1);
|
||||
if (NextTok.is(tok::r_paren)) {
|
||||
RParen = NextTok;
|
||||
// Eat the '*' if it is present.
|
||||
if (StarTok.is(tok::star))
|
||||
ConsumeToken();
|
||||
PP.EnterToken(Tok1);
|
||||
r_parenLoc = ConsumeParen();
|
||||
}
|
||||
} else if (Tok1.is(tok::star)) {
|
||||
Token Tok2 = GetLookAheadToken(1);
|
||||
if (Tok2.is(tok::identifier)) {
|
||||
Token Tok3 = GetLookAheadToken(2);
|
||||
if (Tok3.is(tok::r_paren)) {
|
||||
ConsumeToken();
|
||||
ConsumeToken();
|
||||
PP.EnterToken(Tok2);
|
||||
PP.EnterToken(Tok1);
|
||||
r_parenLoc = ConsumeParen();
|
||||
}
|
||||
}
|
||||
// Eat the identifier.
|
||||
ConsumeToken();
|
||||
// Add the identifier token back.
|
||||
PP.EnterToken(IdentifierTok);
|
||||
// Add the '*' back if it was present.
|
||||
if (StarTok.is(tok::star))
|
||||
PP.EnterToken(StarTok);
|
||||
// Eat the ')'.
|
||||
ConsumeParen();
|
||||
}
|
||||
|
||||
Diag(l_parenLoc, diag::err_paren_after_colon_colon)
|
||||
<< FixItHint::CreateRemoval(l_parenLoc)
|
||||
<< FixItHint::CreateRemoval(r_parenLoc);
|
||||
Diag(LParen.getLocation(), diag::err_paren_after_colon_colon)
|
||||
<< FixItHint::CreateRemoval(LParen.getLocation())
|
||||
<< FixItHint::CreateRemoval(RParen.getLocation());
|
||||
}
|
||||
|
||||
/// \brief Parse global scope or nested-name-specifier if present.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clang_cc1 %s -fsyntax-only -verify
|
||||
// RUN: %clang_cc1 %s -fsyntax-only -verify -DPR21815
|
||||
// RUN: cp %s %t
|
||||
// RUN: not %clang_cc1 -x c++ -fixit %t
|
||||
// RUN: %clang_cc1 -x c++ %t
|
||||
|
@ -20,3 +20,11 @@ void foo() {
|
|||
a = ::(h; // expected-error{{unexpected parenthesis after '::'}}
|
||||
a = ::i;
|
||||
}
|
||||
|
||||
#ifdef PR21815
|
||||
// expected-error@+4{{C++ requires a type specifier for all declarations}}
|
||||
// expected-error@+3{{expected unqualified-id}}
|
||||
// expected-error@+3{{expected expression}}
|
||||
// expected-error@+1{{expected ';' after top level declarator}}
|
||||
a (::(
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue