[clang] fc866fd - [clang] Don't preserve the typo expr in the recovery expr for invalid VarDecls (#90948)
via cfe-commits
cfe-commits at lists.llvm.org
Tue May 7 00:10:33 PDT 2024
Author: Haojian Wu
Date: 2024-05-07T09:10:29+02:00
New Revision: fc866fd2a2cfca6d62f48dcf83778959fd24f559
URL: https://github.com/llvm/llvm-project/commit/fc866fd2a2cfca6d62f48dcf83778959fd24f559
DIFF: https://github.com/llvm/llvm-project/commit/fc866fd2a2cfca6d62f48dcf83778959fd24f559.diff
LOG: [clang] Don't preserve the typo expr in the recovery expr for invalid VarDecls (#90948)
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
node. We should use the one after the typo correction.
This is spotted by a clangd hover crash on the testcase.
Added:
Modified:
clang-tools-extra/clangd/unittests/HoverTests.cpp
clang/lib/Sema/SemaDecl.cpp
clang/test/AST/ast-dump-recovery.cpp
Removed:
################################################################################
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..590f37837eb2df 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);
+ SmallVector<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() {
More information about the cfe-commits
mailing list