[clang] [Clang] Fix the for 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
Thu Sep 7 04:31:36 PDT 2023
https://github.com/yronglin updated https://github.com/llvm/llvm-project/pull/65381:
>From 1eb3e96d9cfc843139e6198b59bed56bac288a3c Mon Sep 17 00:00:00 2001
From: yronglin <yronglin777 at gmail.com>
Date: Wed, 6 Sep 2023 00:00:18 +0800
Subject: [PATCH 1/2] [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 + {{}}
>From 712eb699caf7ecf958bcc2a9ee81b9fca967c4d7 Mon Sep 17 00:00:00 2001
From: yronglin <yronglin777 at gmail.com>
Date: Thu, 7 Sep 2023 19:26:19 +0800
Subject: [PATCH 2/2] Address comments
Co-authored-by: Shafik Yaghmour <shafik at users.noreply.github.com>
---
clang/lib/Parse/ParseStmt.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 9c6327b56591194..fb883c08a745cfa 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -2161,10 +2161,10 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
SourceLocation SecondPartStart = Tok.getLocation();
Sema::ConditionKind CK = Sema::ConditionKind::Boolean;
SecondPart = ParseCXXCondition(
- nullptr, ForLoc, CK,
+ /*InitStmt=*/nullptr, ForLoc, CK,
// FIXME: recovery if we don't see another semi!
/*MissingOK=*/true, MightBeForRangeStmt ? &ForRangeInfo : nullptr,
- /*EnterForConditionScope*/ true);
+ /*EnterForConditionScope=*/true);
if (ForRangeInfo.ParsedForRangeDecl()) {
Diag(FirstPart.get() ? FirstPart.get()->getBeginLoc()
More information about the cfe-commits
mailing list