mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 18:01:07 +01:00
Handle recursion limit errors in postfix expressions (#1081)
This commit is contained in:
@@ -1265,5 +1265,20 @@ TEST_F(ParseTreeTest, RecursionLimit) {
|
||||
EXPECT_TRUE(tree.HasErrors());
|
||||
}
|
||||
|
||||
TEST_F(ParseTreeTest, ParsePostfixExpressionRegression) {
|
||||
// Stack depth errors could cause ParsePostfixExpression to infinitely loop
|
||||
// when calling children and those children error. Because of the fragility of
|
||||
// stack depth, this tries a few different values.
|
||||
for (int n = 0; n <= 10; ++n) {
|
||||
std::string code = "var x: auto = ";
|
||||
code.append(ParseTree::StackDepthLimit - n, '*');
|
||||
code += "(z);";
|
||||
TokenizedBuffer tokens = GetTokenizedBuffer(code);
|
||||
ASSERT_FALSE(tokens.HasErrors());
|
||||
ParseTree tree = ParseTree::Parse(tokens, consumer);
|
||||
EXPECT_TRUE(tree.HasErrors());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace Carbon::Testing
|
||||
|
||||
@@ -912,6 +912,7 @@ auto ParseTree::Parser::ParsePostfixExpression() -> llvm::Optional<Node> {
|
||||
auto start = GetSubtreeStartPosition();
|
||||
llvm::Optional<Node> expression = ParsePrimaryExpression();
|
||||
|
||||
TokenizedBuffer::TokenIterator last_position = position_;
|
||||
while (true) {
|
||||
switch (NextTokenKind()) {
|
||||
case TokenKind::Period():
|
||||
@@ -923,10 +924,16 @@ auto ParseTree::Parser::ParsePostfixExpression() -> llvm::Optional<Node> {
|
||||
expression = ParseCallExpression(start, !expression);
|
||||
break;
|
||||
|
||||
default: {
|
||||
default:
|
||||
return expression;
|
||||
}
|
||||
}
|
||||
// This is subject to an infinite loop if a child call fails, so monitor for
|
||||
// stalling.
|
||||
if (last_position == position_) {
|
||||
CHECK(expression == llvm::None);
|
||||
return expression;
|
||||
}
|
||||
last_position = position_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user