[clang] [clang-tools-extra] [clang] Don't preserve the typo expr in the recovery expr for invalid VarDecls (PR #90948)
Haojian Wu via cfe-commits
cfe-commits at lists.llvm.org
Mon May 6 11:16:44 PDT 2024
https://github.com/hokein updated https://github.com/llvm/llvm-project/pull/90948
>From 2f29011bae5bf1b285c2ab1700c887d74eaec4b0 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Fri, 3 May 2024 10:06:39 +0200
Subject: [PATCH 1/2] [clang] Don't preserve the typo expr in the recovery expr
for invalid VarDecls.
With the commit d5308949cf884d8e4b971d51a8b4f73584c4adec, we now
preserve the initializer for invalid decls with the recovery-expr.
However there is a chance that the original init expr is a typo-expr, we
should not preserve it in the final AST, as typo-expr is an internal AST
nodes. We should use the one after the typo correction.
This is spotted by a clangd hover crash on the testcase.
---
clang-tools-extra/clangd/unittests/HoverTests.cpp | 13 +++++++++++++
clang/lib/Sema/SemaDecl.cpp | 7 +++++--
clang/test/AST/ast-dump-recovery.cpp | 5 +++++
3 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 5ead74748f550c..28df24f34827c0 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -965,6 +965,19 @@ class Foo final {})cpp";
// Bindings are in theory public members of an anonymous struct.
HI.AccessSpecifier = "public";
}},
+ {// Don't crash on invalid decl with invalid init expr.
+ R"cpp(
+ Unknown [[^abc]] = invalid;
+ // error-ok
+ )cpp",
+ [](HoverInfo &HI) {
+ HI.Name = "abc";
+ HI.Kind = index::SymbolKind::Variable;
+ HI.NamespaceScope = "";
+ HI.Definition = "int abc = <recovery - expr>()";
+ HI.Type = "int";
+ HI.AccessSpecifier = "public";
+ }},
{// Extra info for function call.
R"cpp(
void fun(int arg_a, int &arg_b) {};
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 19968452f0d566..169df60b56bb4b 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -13530,9 +13530,12 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
}
if (VDecl->isInvalidDecl()) {
- CorrectDelayedTyposInExpr(Init, VDecl);
+ ExprResult Res = CorrectDelayedTyposInExpr(Init, VDecl);
+ std::vector<Expr *> SubExprs;
+ if (Res.isUsable())
+ SubExprs.push_back(Res.get());
ExprResult Recovery =
- CreateRecoveryExpr(Init->getBeginLoc(), Init->getEndLoc(), {Init});
+ CreateRecoveryExpr(Init->getBeginLoc(), Init->getEndLoc(), SubExprs);
if (Expr *E = Recovery.get())
VDecl->setInit(E);
return;
diff --git a/clang/test/AST/ast-dump-recovery.cpp b/clang/test/AST/ast-dump-recovery.cpp
index 77527743fe8577..a88dff471d9f04 100644
--- a/clang/test/AST/ast-dump-recovery.cpp
+++ b/clang/test/AST/ast-dump-recovery.cpp
@@ -419,6 +419,11 @@ void InitializerOfInvalidDecl() {
// CHECK: VarDecl {{.*}} invalid InvalidDecl
// CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>' contains-errors
// CHECK-NEXT: `-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'ValidDecl'
+
+ Unknown InvalidDeclWithInvalidInit = Invalid;
+ // CHECK: VarDecl {{.*}} invalid InvalidDeclWithInvalidInit
+ // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>' contains-errors
+ // CHECK-NOT: `-TypoExpr
}
void RecoverToAnInvalidDecl() {
>From 06c30958b7bb2c664440e47bd2257e068f72c2b1 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Mon, 6 May 2024 20:16:05 +0200
Subject: [PATCH 2/2] address review comments.
---
clang/lib/Sema/SemaDecl.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 169df60b56bb4b..590f37837eb2df 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -13531,7 +13531,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
if (VDecl->isInvalidDecl()) {
ExprResult Res = CorrectDelayedTyposInExpr(Init, VDecl);
- std::vector<Expr *> SubExprs;
+ SmallVector<Expr *> SubExprs;
if (Res.isUsable())
SubExprs.push_back(Res.get());
ExprResult Recovery =
More information about the cfe-commits
mailing list