[clang] [Clang] Fix the do while statement disappearing in AST when an error occurs in the conditional expression of the for statement (PR #65381)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 5 09:47:05 PDT 2023
https://github.com/yronglin created https://github.com/llvm/llvm-project/pull/65381:
None
>From ee5c987880d4c9d9fec1780e28833b30b2753faa Mon Sep 17 00:00:00 2001
From: yronglin <yronglin777 at gmail.com>
Date: Wed, 6 Sep 2023 00:00:18 +0800
Subject: [PATCH] [Clang] Fix the do while statement disappearing in AST when
an error occurs in the conditional expression of the for statement
---
clang/lib/Parse/ParseStmt.cpp | 17 ++++++++++++++++-
clang/test/AST/ast-dump-recovery.cpp | 15 +++++++++++++++
.../constexpr-function-recovery-crash.cpp | 1 +
3 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 110806ef0c77d63..9c6327b56591194 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -2158,8 +2158,10 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
// for-range-declaration next.
bool MightBeForRangeStmt = !ForRangeInfo.ParsedForRangeDecl();
ColonProtectionRAIIObject ColonProtection(*this, MightBeForRangeStmt);
+ SourceLocation SecondPartStart = Tok.getLocation();
+ Sema::ConditionKind CK = Sema::ConditionKind::Boolean;
SecondPart = ParseCXXCondition(
- nullptr, ForLoc, Sema::ConditionKind::Boolean,
+ nullptr, ForLoc, CK,
// FIXME: recovery if we don't see another semi!
/*MissingOK=*/true, MightBeForRangeStmt ? &ForRangeInfo : nullptr,
/*EnterForConditionScope*/ true);
@@ -2178,6 +2180,19 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
<< FixItHint::CreateRemoval(EmptyInitStmtSemiLoc);
}
}
+
+ if (SecondPart.isInvalid()) {
+ ExprResult CondExpr = Actions.CreateRecoveryExpr(
+ SecondPartStart,
+ Tok.getLocation() == SecondPartStart ? SecondPartStart
+ : PrevTokLocation,
+ {}, Actions.PreferredConditionType(CK));
+ if (!CondExpr.isInvalid())
+ SecondPart = Actions.ActOnCondition(getCurScope(), ForLoc,
+ CondExpr.get(), CK,
+ /*MissingOK=*/false);
+ }
+
} else {
// We permit 'continue' and 'break' in the condition of a for loop.
getCurScope()->AddFlags(Scope::BreakScope | Scope::ContinueScope);
diff --git a/clang/test/AST/ast-dump-recovery.cpp b/clang/test/AST/ast-dump-recovery.cpp
index c882b4659a7310e..278b9fc000b5740 100644
--- a/clang/test/AST/ast-dump-recovery.cpp
+++ b/clang/test/AST/ast-dump-recovery.cpp
@@ -432,3 +432,18 @@ void RecoveryToDoWhileStmtCond() {
// CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 10
do {} while (some_invalid_val + 1 < 10);
}
+
+void RecoveryForStmtCond() {
+ // CHECK:FunctionDecl {{.*}} RecoveryForStmtCond
+ // CHECK-NEXT:`-CompoundStmt {{.*}}
+ // CHECK-NEXT: `-ForStmt {{.*}}
+ // CHECK-NEXT: |-DeclStmt {{.*}}
+ // CHECK-NEXT: | `-VarDecl {{.*}}
+ // CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+ // CHECK-NEXT: |-<<<NULL>>>
+ // CHECK-NEXT: |-RecoveryExpr {{.*}} 'bool' contains-errors
+ // CHECK-NEXT: |-UnaryOperator {{.*}} 'int' lvalue prefix '++'
+ // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'i' 'int'
+ // CHECK-NEXT: `-CompoundStmt {{.*}}
+ for (int i = 0; i < invalid; ++i) {}
+}
diff --git a/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp b/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
index e1d97ceafbe9d15..90ee7892b2fc2e7 100644
--- a/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
+++ b/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
@@ -106,3 +106,4 @@ TEST_EVALUATE(ForCond, for (; !!;){};);// expected-error + {{}}
TEST_EVALUATE(ForInc, for (;; !!){};);// expected-error + {{}}
// expected-note at -1 + {{infinite loop}}
// expected-note at -2 {{in call}}
+TEST_EVALUATE(ForCondUnDef, for (;some_cond;){};); // expected-error + {{}}
More information about the cfe-commits
mailing list