зеркало из https://github.com/microsoft/clang-1.git
When finding a '(' after '::', emit error with hint to remove '(' and matching
')', if found. Don't crash. Fixes PR11852. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@167268 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
aee56faf90
Коммит
919b9557b4
|
@ -348,6 +348,8 @@ def ext_c11_static_assert : Extension<
|
|||
def warn_cxx98_compat_static_assert : Warning<
|
||||
"static_assert declarations are incompatible with C++98">,
|
||||
InGroup<CXX98Compat>, DefaultIgnore;
|
||||
def err_paren_after_colon_colon : Error<
|
||||
"unexpected parentheses after '::'">;
|
||||
|
||||
/// Objective-C parser diagnostics
|
||||
def err_expected_minus_or_plus : Error<
|
||||
|
|
|
@ -1327,6 +1327,8 @@ private:
|
|||
bool *MayBePseudoDestructor = 0,
|
||||
bool IsTypename = false);
|
||||
|
||||
void CheckForLParenAfterColonColon();
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// C++0x 5.1.2: Lambda expressions
|
||||
|
||||
|
|
|
@ -96,6 +96,45 @@ void Parser::CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectType,
|
|||
/*AtDigraph*/false);
|
||||
}
|
||||
|
||||
/// \brief Emits an error for a left parentheses after a double colon.
|
||||
///
|
||||
/// When a '(' is found after a '::', emit an error. Attempt to fix the token
|
||||
/// stream by removing the '(', and the matching ')' if it found.
|
||||
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))
|
||||
return;
|
||||
|
||||
if (Tok1.is(tok::identifier)) {
|
||||
Token Tok2 = GetLookAheadToken(1);
|
||||
if (Tok2.is(tok::r_paren)) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Diag(l_parenLoc, diag::err_paren_after_colon_colon)
|
||||
<< FixItHint::CreateRemoval(l_parenLoc)
|
||||
<< FixItHint::CreateRemoval(r_parenLoc);
|
||||
}
|
||||
|
||||
/// \brief Parse global scope or nested-name-specifier if present.
|
||||
///
|
||||
/// Parses a C++ global scope specifier ('::') or nested-name-specifier (which
|
||||
|
@ -160,7 +199,9 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
|
|||
// '::' - Global scope qualifier.
|
||||
if (Actions.ActOnCXXGlobalScopeSpecifier(getCurScope(), ConsumeToken(), SS))
|
||||
return true;
|
||||
|
||||
|
||||
CheckForLParenAfterColonColon();
|
||||
|
||||
HasScopeSpecifier = true;
|
||||
}
|
||||
|
||||
|
@ -371,6 +412,8 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
|
|||
"NextToken() not working properly!");
|
||||
SourceLocation CCLoc = ConsumeToken();
|
||||
|
||||
CheckForLParenAfterColonColon();
|
||||
|
||||
HasScopeSpecifier = true;
|
||||
if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(), II, IdLoc, CCLoc,
|
||||
ObjectType, EnteringContext, SS))
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
// RUN: %clang_cc1 %s -fsyntax-only -verify
|
||||
// RUN: cp %s %t
|
||||
// RUN: not %clang_cc1 -x c++ -fixit %t
|
||||
// RUN: %clang_cc1 -x c++ %t
|
||||
|
||||
struct S { static int a,b,c;};
|
||||
int S::(a); // expected-error{{unexpected parentheses after '::'}}
|
||||
int S::(b; // expected-error{{unexpected parentheses after '::'}}
|
||||
int S::c;
|
||||
int S::(*d); // expected-error{{unexpected parentheses after '::'}}
|
||||
int S::(*e; // expected-error{{unexpected parentheses after '::'}}
|
||||
int S::*f;
|
||||
int g = S::(a); // expected-error{{unexpected parentheses after '::'}}
|
||||
int h = S::(b; // expected-error{{unexpected parentheses after '::'}}
|
||||
int i = S::c;
|
||||
|
||||
void foo() {
|
||||
int a;
|
||||
a = ::(g); // expected-error{{unexpected parentheses after '::'}}
|
||||
a = ::(h; // expected-error{{unexpected parentheses after '::'}}
|
||||
a = ::i;
|
||||
}
|
Загрузка…
Ссылка в новой задаче