Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit 7fd3a64

Browse files
committed
When "delayed parsing" C++ default arguments, if there is an error, there may be tokens left in the token stream
that will interfere (they will be parsed as if they are after the class' '}') and a crash will occur because the CachedTokens that holds them will be deleted while the lexer is still using them. Make sure that the tokens of default args are removed from the token stream. Fixes PR6647. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99939 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 3be9678 commit 7fd3a64

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

lib/Parse/ParseCXXInlineMethods.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) {
122122
Actions.ActOnDelayedCXXMethodParameter(CurScope, LM.DefaultArgs[I].Param);
123123

124124
if (CachedTokens *Toks = LM.DefaultArgs[I].Toks) {
125+
// Save the current token position.
126+
SourceLocation origLoc = Tok.getLocation();
127+
125128
// Parse the default argument from its saved token stream.
126129
Toks->push_back(Tok); // So that the current token doesn't get lost
127130
PP.EnterTokenStream(&Toks->front(), Toks->size(), true, false);
@@ -139,6 +142,15 @@ void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) {
139142
else
140143
Actions.ActOnParamDefaultArgument(LM.DefaultArgs[I].Param, EqualLoc,
141144
move(DefArgResult));
145+
146+
assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc,
147+
Tok.getLocation()) &&
148+
"ParseAssignmentExpression went over the default arg tokens!");
149+
// There could be leftover tokens (e.g. because of an error).
150+
// Skip through until we reach the original token position.
151+
while (Tok.getLocation() != origLoc)
152+
ConsumeAnyToken();
153+
142154
delete Toks;
143155
LM.DefaultArgs[I].Toks = 0;
144156
}

test/Parser/cxx-default-args.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %clang_cc1 -fsyntax-only -verify %s
2+
3+
// PR6647
4+
class C {
5+
// After the error, the rest of the tokens inside the default arg should be
6+
// skipped, avoiding a "expected ';' after class" after 'undecl'.
7+
void m(int x = undecl + 0); // expected-error {{use of undeclared identifier 'undecl'}}
8+
};
9+

0 commit comments

Comments
 (0)