Skip to content

Commit fc866fd

Browse files
authored
[clang] Don't preserve the typo expr in the recovery expr for invalid VarDecls (#90948)
With the commit d530894, 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.
1 parent 2b9210d commit fc866fd

File tree

3 files changed

+23
-2
lines changed

3 files changed

+23
-2
lines changed

clang-tools-extra/clangd/unittests/HoverTests.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,19 @@ class Foo final {})cpp";
965965
// Bindings are in theory public members of an anonymous struct.
966966
HI.AccessSpecifier = "public";
967967
}},
968+
{// Don't crash on invalid decl with invalid init expr.
969+
R"cpp(
970+
Unknown [[^abc]] = invalid;
971+
// error-ok
972+
)cpp",
973+
[](HoverInfo &HI) {
974+
HI.Name = "abc";
975+
HI.Kind = index::SymbolKind::Variable;
976+
HI.NamespaceScope = "";
977+
HI.Definition = "int abc = <recovery - expr>()";
978+
HI.Type = "int";
979+
HI.AccessSpecifier = "public";
980+
}},
968981
{// Extra info for function call.
969982
R"cpp(
970983
void fun(int arg_a, int &arg_b) {};

clang/lib/Sema/SemaDecl.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13530,9 +13530,12 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
1353013530
}
1353113531

1353213532
if (VDecl->isInvalidDecl()) {
13533-
CorrectDelayedTyposInExpr(Init, VDecl);
13533+
ExprResult Res = CorrectDelayedTyposInExpr(Init, VDecl);
13534+
SmallVector<Expr *> SubExprs;
13535+
if (Res.isUsable())
13536+
SubExprs.push_back(Res.get());
1353413537
ExprResult Recovery =
13535-
CreateRecoveryExpr(Init->getBeginLoc(), Init->getEndLoc(), {Init});
13538+
CreateRecoveryExpr(Init->getBeginLoc(), Init->getEndLoc(), SubExprs);
1353613539
if (Expr *E = Recovery.get())
1353713540
VDecl->setInit(E);
1353813541
return;

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,11 @@ void InitializerOfInvalidDecl() {
419419
// CHECK: VarDecl {{.*}} invalid InvalidDecl
420420
// CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>' contains-errors
421421
// CHECK-NEXT: `-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'ValidDecl'
422+
423+
Unknown InvalidDeclWithInvalidInit = Invalid;
424+
// CHECK: VarDecl {{.*}} invalid InvalidDeclWithInvalidInit
425+
// CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>' contains-errors
426+
// CHECK-NOT: `-TypoExpr
422427
}
423428

424429
void RecoverToAnInvalidDecl() {

0 commit comments

Comments
 (0)