r216518 - PR20760: Don't assert (and produce better diagnostics) if a default initializer
Richard Smith
richard-llvm at metafoo.co.uk
Tue Aug 26 20:23:12 PDT 2014
Author: rsmith
Date: Tue Aug 26 22:23:12 2014
New Revision: 216518
URL: http://llvm.org/viewvc/llvm-project?rev=216518&view=rev
Log:
PR20760: Don't assert (and produce better diagnostics) if a default initializer
contains an unmatched closing bracket token.
Modified:
cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/test/Parser/cxx-class.cpp
Modified: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=216518&r1=216517&r2=216518&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp (original)
+++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp Tue Aug 26 22:23:12 2014
@@ -540,11 +540,13 @@ void Parser::ParseLexedMemberInitializer
// The next token should be our artificial terminating EOF token.
if (Tok.isNot(tok::eof)) {
- SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation);
- if (!EndLoc.isValid())
- EndLoc = Tok.getLocation();
- // No fixit; we can't recover as if there were a semicolon here.
- Diag(EndLoc, diag::err_expected_semi_decl_list);
+ if (!Init.isInvalid()) {
+ SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation);
+ if (!EndLoc.isValid())
+ EndLoc = Tok.getLocation();
+ // No fixit; we can't recover as if there were a semicolon here.
+ Diag(EndLoc, diag::err_expected_semi_decl_list);
+ }
// Consume tokens until we hit the artificial EOF.
while (Tok.isNot(tok::eof))
@@ -891,11 +893,13 @@ private:
/// ConsumeAndStoreInitializer - Consume and store the token at the passed token
/// container until the end of the current initializer expression (either a
/// default argument or an in-class initializer for a non-static data member).
-/// The final token is not consumed.
+///
+/// Returns \c true if we reached the end of something initializer-shaped,
+/// \c false if we bailed out.
bool Parser::ConsumeAndStoreInitializer(CachedTokens &Toks,
CachedInitKind CIK) {
// We always want this function to consume at least one token if not at EOF.
- bool IsFirstTokenConsumed = true;
+ bool IsFirstToken = true;
// Number of possible unclosed <s we've seen so far. These might be templates,
// and might not, but if there were none of them (or we know for sure that
@@ -1064,21 +1068,28 @@ bool Parser::ConsumeAndStoreInitializer(
// Since the user wasn't looking for this token (if they were, it would
// already be handled), this isn't balanced. If there is a LHS token at a
// higher level, we will assume that this matches the unbalanced token
- // and return it. Otherwise, this is a spurious RHS token, which we skip.
+ // and return it. Otherwise, this is a spurious RHS token, which we
+ // consume and pass on to downstream code to diagnose.
case tok::r_paren:
if (CIK == CIK_DefaultArgument)
return true; // End of the default argument.
- if (ParenCount && !IsFirstTokenConsumed)
- return false; // Matches something.
- goto consume_token;
+ if (ParenCount && !IsFirstToken)
+ return false;
+ Toks.push_back(Tok);
+ ConsumeParen();
+ continue;
case tok::r_square:
- if (BracketCount && !IsFirstTokenConsumed)
- return false; // Matches something.
- goto consume_token;
+ if (BracketCount && !IsFirstToken)
+ return false;
+ Toks.push_back(Tok);
+ ConsumeBracket();
+ continue;
case tok::r_brace:
- if (BraceCount && !IsFirstTokenConsumed)
- return false; // Matches something.
- goto consume_token;
+ if (BraceCount && !IsFirstToken)
+ return false;
+ Toks.push_back(Tok);
+ ConsumeBrace();
+ continue;
case tok::code_completion:
Toks.push_back(Tok);
@@ -1103,6 +1114,6 @@ bool Parser::ConsumeAndStoreInitializer(
ConsumeToken();
break;
}
- IsFirstTokenConsumed = false;
+ IsFirstToken = false;
}
}
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=216518&r1=216517&r2=216518&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Tue Aug 26 22:23:12 2014
@@ -5438,8 +5438,7 @@ void Parser::ParseParameterDeclarationCl
// Inform the actions module about the parameter declarator, so it gets
// added to the current scope.
- Decl *Param = Actions.ActOnParamDeclarator(getCurScope(),
- ParmDeclarator);
+ Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDeclarator);
// Parse the default argument, if any. We parse the default
// arguments in all dialects; the semantic analysis in
// ActOnParamDefaultArgument will reject the default argument in
Modified: cfe/trunk/test/Parser/cxx-class.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-class.cpp?rev=216518&r1=216517&r2=216518&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx-class.cpp (original)
+++ cfe/trunk/test/Parser/cxx-class.cpp Tue Aug 26 22:23:12 2014
@@ -149,6 +149,17 @@ namespace BadFriend {
};
}
+class PR20760_a {
+ int a = ); // expected-warning {{extension}} expected-error {{expected expression}}
+ int b = }; // expected-warning {{extension}} expected-error {{expected expression}}
+ int c = ]; // expected-warning {{extension}} expected-error {{expected expression}}
+};
+class PR20760_b {
+ int d = d); // expected-warning {{extension}} expected-error {{expected ';'}}
+ int e = d]; // expected-warning {{extension}} expected-error {{expected ';'}}
+ int f = d // expected-warning {{extension}} expected-error {{expected ';'}}
+};
+
// PR11109 must appear at the end of the source file
class pr11109r3 { // expected-note{{to match this '{'}}
public // expected-error{{expected ':'}} expected-error{{expected '}'}} expected-error{{expected ';' after class}}
More information about the cfe-commits
mailing list