diff options
-rw-r--r-- | clang/lib/Parse/ParseCXXInlineMethods.cpp | 12 | ||||
-rw-r--r-- | clang/test/Parser/cxx-default-args.cpp | 9 |
2 files changed, 21 insertions, 0 deletions
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index f1e639c2957..44a14c33159 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -122,6 +122,9 @@ void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) { Actions.ActOnDelayedCXXMethodParameter(CurScope, LM.DefaultArgs[I].Param); if (CachedTokens *Toks = LM.DefaultArgs[I].Toks) { + // Save the current token position. + SourceLocation origLoc = Tok.getLocation(); + // Parse the default argument from its saved token stream. Toks->push_back(Tok); // So that the current token doesn't get lost PP.EnterTokenStream(&Toks->front(), Toks->size(), true, false); @@ -139,6 +142,15 @@ void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) { else Actions.ActOnParamDefaultArgument(LM.DefaultArgs[I].Param, EqualLoc, move(DefArgResult)); + + assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc, + Tok.getLocation()) && + "ParseAssignmentExpression went over the default arg tokens!"); + // There could be leftover tokens (e.g. because of an error). + // Skip through until we reach the original token position. + while (Tok.getLocation() != origLoc) + ConsumeAnyToken(); + delete Toks; LM.DefaultArgs[I].Toks = 0; } diff --git a/clang/test/Parser/cxx-default-args.cpp b/clang/test/Parser/cxx-default-args.cpp new file mode 100644 index 00000000000..a084fb0812b --- /dev/null +++ b/clang/test/Parser/cxx-default-args.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// PR6647 +class C { + // After the error, the rest of the tokens inside the default arg should be + // skipped, avoiding a "expected ';' after class" after 'undecl'. + void m(int x = undecl + 0); // expected-error {{use of undeclared identifier 'undecl'}} +}; + |