Skip to content

Commit 1a0d466

Browse files
committed
[AST] Preserve the invalid initializer for auto VarDecl.
Fixes clangd/clangd#330 Reviewers: sammccall Tags: #clang Differential Revision: https://reviews.llvm.org/D78365
1 parent f17eb4e commit 1a0d466

File tree

3 files changed

+28
-5
lines changed

3 files changed

+28
-5
lines changed

clang/lib/Sema/SemaDecl.cpp

+9-1
Original file line numberDiff line numberDiff line change
@@ -11847,10 +11847,18 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
1184711847
// be deduced based on the chosen correction if the original init contains a
1184811848
// TypoExpr.
1184911849
ExprResult Res = CorrectDelayedTyposInExpr(Init, VDecl);
11850-
if (!Res.isUsable() || Res.get()->containsErrors()) {
11850+
if (!Res.isUsable()) {
11851+
// There are unresolved typos in Init, just drop them.
11852+
// FIXME: improve the recovery strategy to preserve the Init.
1185111853
RealDecl->setInvalidDecl();
1185211854
return;
1185311855
}
11856+
if (Res.get()->containsErrors()) {
11857+
// Invalidate the decl as we don't know the type for recovery-expr yet.
11858+
RealDecl->setInvalidDecl();
11859+
VDecl->setInit(Res.get());
11860+
return;
11861+
}
1185411862
Init = Res.get();
1185511863

1185611864
if (DeduceVariableDeclarationType(VDecl, DirectInit, Init))

clang/test/AST/ast-dump-expr-errors.cpp

-4
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,6 @@ int c = &(bar() + baz()) * 10;
4040
// CHECK-NEXT:| `-IntegerLiteral {{.*}} 1
4141
int d = static_cast<int>(bar() + 1);
4242

43-
// FIXME: store initializer even when 'auto' could not be deduced.
44-
// Expressions with errors currently do not keep initializers around.
45-
// CHECK: -VarDecl {{.*}} invalid e 'auto'
46-
auto e = bar();
4743

4844
// Error type should result in an invalid decl.
4945
// CHECK: -VarDecl {{.*}} invalid f 'decltype(<recovery-expr>(bar))'

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

+19
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,22 @@ void InvalidInitalizer(int x) {
156156
// CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'invalid'
157157
Bar b6 = Bar{invalid()};
158158
}
159+
void InitializerForAuto() {
160+
// CHECK: `-VarDecl {{.*}} invalid a 'auto'
161+
// CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>' contains-errors
162+
// CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'invalid'
163+
auto a = invalid();
164+
165+
// CHECK: `-VarDecl {{.*}} invalid b 'auto'
166+
// CHECK-NEXT: `-CallExpr {{.*}} '<dependent type>' contains-errors
167+
// CHECK-NEXT: |-UnresolvedLookupExpr {{.*}} 'some_func'
168+
// CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>' contains-errors
169+
// CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'invalid'
170+
auto b = some_func(invalid());
171+
172+
decltype(ned);
173+
// very bad initailizer: there is an unresolved typo expr internally, we just
174+
// drop it.
175+
// CHECK: `-VarDecl {{.*}} invalid unresolved_typo 'auto'
176+
auto unresolved_typo = gned.*[] {};
177+
}

0 commit comments

Comments
 (0)