diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-08-27 03:23:12 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-08-27 03:23:12 +0000 |
commit | 95e1fb0c5fdefe19a566d07672b5551ef61004d3 (patch) | |
tree | db595643e186cfe9266d570e743d6bfb99e09f17 /clang/lib/Parse/ParseCXXInlineMethods.cpp | |
parent | 3af6c10afb2ade27c535bd42cdd975fe2f8b4ec8 (diff) | |
download | bcm5719-llvm-95e1fb0c5fdefe19a566d07672b5551ef61004d3.tar.gz bcm5719-llvm-95e1fb0c5fdefe19a566d07672b5551ef61004d3.zip |
PR20760: Don't assert (and produce better diagnostics) if a default initializer
contains an unmatched closing bracket token.
llvm-svn: 216518
Diffstat (limited to 'clang/lib/Parse/ParseCXXInlineMethods.cpp')
-rw-r--r-- | clang/lib/Parse/ParseCXXInlineMethods.cpp | 47 |
1 files changed, 29 insertions, 18 deletions
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index 55caa5e59f6..3571d5ab413 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -540,11 +540,13 @@ void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) { // 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(CachedTokens &Toks, // 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(CachedTokens &Toks, ConsumeToken(); break; } - IsFirstTokenConsumed = false; + IsFirstToken = false; } } |