Skip to content

Commit 45c81c1

Browse files
committed
---
yaml --- r: 347227 b: refs/heads/master c: ece85b0 h: refs/heads/master i: 347225: 9e5417d 347223: 49d52a7
1 parent 304e404 commit 45c81c1

File tree

3 files changed

+25
-3
lines changed

3 files changed

+25
-3
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: da11d8e005bd8597e78c4470aa7e83ec4759f162
2+
refs/heads/master: ece85b09e302697175dac85a70147a7ef88702f6
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/include/swift/Parse/Parser.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,22 @@ class Parser {
230230
// Cut off parsing by acting as if we reached the end-of-file.
231231
Tok.setKind(tok::eof);
232232
}
233-
233+
234+
/// Use this to assert that the parser has advanced the lexing location, e.g.
235+
/// before a specific parser function has returned.
236+
class AssertParserMadeProgressBeforeLeavingScopeRAII {
237+
Parser &P;
238+
SourceLoc InitialLoc;
239+
public:
240+
AssertParserMadeProgressBeforeLeavingScopeRAII(Parser &parser) : P(parser) {
241+
InitialLoc = P.Tok.getLoc();
242+
}
243+
~AssertParserMadeProgressBeforeLeavingScopeRAII() {
244+
assert(InitialLoc != P.Tok.getLoc() &&
245+
"parser did not make progress, this can result in infinite loop");
246+
}
247+
};
248+
234249
/// A RAII object for temporarily changing CurDeclContext.
235250
class ContextChange {
236251
protected:

trunk/lib/Parse/ParseStmt.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ using namespace swift::syntax;
3636
/// isStartOfStmt - Return true if the current token starts a statement.
3737
///
3838
bool Parser::isStartOfStmt() {
39+
// This needs to be kept in sync with `Parser::parseStmt()`. If a new token
40+
// kind is accepted here as start of statement, it should also be handled in
41+
// `Parser::parseStmt()`.
3942
switch (Tok.getKind()) {
4043
default: return false;
4144
case tok::kw_return:
@@ -565,6 +568,8 @@ static ParserResult<Stmt> recoverFromInvalidCase(Parser &P) {
565568
}
566569

567570
ParserResult<Stmt> Parser::parseStmt() {
571+
AssertParserMadeProgressBeforeLeavingScopeRAII apmp(*this);
572+
568573
SyntaxParsingContext LocalContext(SyntaxContext, SyntaxContextKind::Stmt);
569574

570575
// Note that we're parsing a statement.
@@ -588,7 +593,9 @@ ParserResult<Stmt> Parser::parseStmt() {
588593
if (isContextualYieldKeyword()) {
589594
Tok.setKind(tok::kw_yield);
590595
}
591-
596+
597+
// This needs to handle everything that `Parser::isStartOfStmt()` accepts as
598+
// start of statement.
592599
switch (Tok.getKind()) {
593600
case tok::pound_line:
594601
case tok::pound_sourceLocation:

0 commit comments

Comments
 (0)