Skip to content

Commit 5b58d71

Browse files
committed
[parser] Add an assertion to ensure that Parser::parseStmt() makes lexing progress before returning
1 parent daae845 commit 5b58d71

File tree

2 files changed

+18
-1
lines changed

2 files changed

+18
-1
lines changed

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:

lib/Parse/ParseStmt.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,8 @@ static ParserResult<Stmt> recoverFromInvalidCase(Parser &P) {
568568
}
569569

570570
ParserResult<Stmt> Parser::parseStmt() {
571+
AssertParserMadeProgressBeforeLeavingScopeRAII apmp(*this);
572+
571573
SyntaxParsingContext LocalContext(SyntaxContext, SyntaxContextKind::Stmt);
572574

573575
// Note that we're parsing a statement.

0 commit comments

Comments
 (0)