Skip to content

Commit 51ba9cb

Browse files
committed
[Clang] Fix the do while statement disappearing in AST when an error occurs in the conditional expression of the for statement
1 parent 4bb9024 commit 51ba9cb

File tree

3 files changed

+32
-1
lines changed

3 files changed

+32
-1
lines changed

clang/lib/Parse/ParseStmt.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2158,8 +2158,10 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
21582158
// for-range-declaration next.
21592159
bool MightBeForRangeStmt = !ForRangeInfo.ParsedForRangeDecl();
21602160
ColonProtectionRAIIObject ColonProtection(*this, MightBeForRangeStmt);
2161+
SourceLocation SecondPartStart = Tok.getLocation();
2162+
Sema::ConditionKind CK = Sema::ConditionKind::Boolean;
21612163
SecondPart = ParseCXXCondition(
2162-
nullptr, ForLoc, Sema::ConditionKind::Boolean,
2164+
nullptr, ForLoc, CK,
21632165
// FIXME: recovery if we don't see another semi!
21642166
/*MissingOK=*/true, MightBeForRangeStmt ? &ForRangeInfo : nullptr,
21652167
/*EnterForConditionScope*/ true);
@@ -2178,6 +2180,19 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
21782180
<< FixItHint::CreateRemoval(EmptyInitStmtSemiLoc);
21792181
}
21802182
}
2183+
2184+
if (SecondPart.isInvalid()) {
2185+
ExprResult CondExpr = Actions.CreateRecoveryExpr(
2186+
SecondPartStart,
2187+
Tok.getLocation() == SecondPartStart ? SecondPartStart
2188+
: PrevTokLocation,
2189+
{}, Actions.PreferredConditionType(CK));
2190+
if (!CondExpr.isInvalid())
2191+
SecondPart = Actions.ActOnCondition(getCurScope(), ForLoc,
2192+
CondExpr.get(), CK,
2193+
/*MissingOK=*/false);
2194+
}
2195+
21812196
} else {
21822197
// We permit 'continue' and 'break' in the condition of a for loop.
21832198
getCurScope()->AddFlags(Scope::BreakScope | Scope::ContinueScope);

clang/test/AST/ast-dump-recovery.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,3 +432,18 @@ void RecoveryToDoWhileStmtCond() {
432432
// CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 10
433433
do {} while (some_invalid_val + 1 < 10);
434434
}
435+
436+
void RecoveryForStmtCond() {
437+
// CHECK:FunctionDecl {{.*}} RecoveryForStmtCond
438+
// CHECK-NEXT:`-CompoundStmt {{.*}}
439+
// CHECK-NEXT: `-ForStmt {{.*}}
440+
// CHECK-NEXT: |-DeclStmt {{.*}}
441+
// CHECK-NEXT: | `-VarDecl {{.*}}
442+
// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:16> 'int' 0
443+
// CHECK-NEXT: |-<<<NULL>>>
444+
// CHECK-NEXT: |-RecoveryExpr {{.*}} 'bool' contains-errors
445+
// CHECK-NEXT: |-UnaryOperator {{.*}} 'int' lvalue prefix '++'
446+
// CHECK-NEXT: | `-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'i' 'int'
447+
// CHECK-NEXT: `-CompoundStmt {{.*}}
448+
for (int i = 0; i < invalid; ++i) {}
449+
}

clang/test/SemaCXX/constexpr-function-recovery-crash.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,4 @@ TEST_EVALUATE(ForCond, for (; !!;){};);// expected-error + {{}}
106106
TEST_EVALUATE(ForInc, for (;; !!){};);// expected-error + {{}}
107107
// expected-note@-1 + {{infinite loop}}
108108
// expected-note@-2 {{in call}}
109+
TEST_EVALUATE(ForCondUnDef, for (;some_cond;){};); // expected-error + {{}}

0 commit comments

Comments
 (0)