Skip to content

Commit

Permalink
[AST] Preserve the invalid initializer for auto VarDecl.
Browse files Browse the repository at this point in the history
Fixes clangd/clangd#330

Reviewers: sammccall

Tags: #clang

Differential Revision: https://reviews.llvm.org/D78365
  • Loading branch information
hokein committed Apr 27, 2020
1 parent f17eb4e commit 1a0d466
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 5 deletions.
10 changes: 9 additions & 1 deletion clang/lib/Sema/SemaDecl.cpp
Expand Up @@ -11847,10 +11847,18 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
// be deduced based on the chosen correction if the original init contains a
// TypoExpr.
ExprResult Res = CorrectDelayedTyposInExpr(Init, VDecl);
if (!Res.isUsable() || Res.get()->containsErrors()) {
if (!Res.isUsable()) {
// There are unresolved typos in Init, just drop them.
// FIXME: improve the recovery strategy to preserve the Init.
RealDecl->setInvalidDecl();
return;
}
if (Res.get()->containsErrors()) {
// Invalidate the decl as we don't know the type for recovery-expr yet.
RealDecl->setInvalidDecl();
VDecl->setInit(Res.get());
return;
}
Init = Res.get();

if (DeduceVariableDeclarationType(VDecl, DirectInit, Init))
Expand Down
4 changes: 0 additions & 4 deletions clang/test/AST/ast-dump-expr-errors.cpp
Expand Up @@ -40,10 +40,6 @@ int c = &(bar() + baz()) * 10;
// CHECK-NEXT:| `-IntegerLiteral {{.*}} 1
int d = static_cast<int>(bar() + 1);

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

// Error type should result in an invalid decl.
// CHECK: -VarDecl {{.*}} invalid f 'decltype(<recovery-expr>(bar))'
Expand Down
19 changes: 19 additions & 0 deletions clang/test/AST/ast-dump-recovery.cpp
Expand Up @@ -156,3 +156,22 @@ void InvalidInitalizer(int x) {
// CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'invalid'
Bar b6 = Bar{invalid()};
}
void InitializerForAuto() {
// CHECK: `-VarDecl {{.*}} invalid a 'auto'
// CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>' contains-errors
// CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'invalid'
auto a = invalid();

// CHECK: `-VarDecl {{.*}} invalid b 'auto'
// CHECK-NEXT: `-CallExpr {{.*}} '<dependent type>' contains-errors
// CHECK-NEXT: |-UnresolvedLookupExpr {{.*}} 'some_func'
// CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>' contains-errors
// CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'invalid'
auto b = some_func(invalid());

decltype(ned);
// very bad initailizer: there is an unresolved typo expr internally, we just
// drop it.
// CHECK: `-VarDecl {{.*}} invalid unresolved_typo 'auto'
auto unresolved_typo = gned.*[] {};
}

0 comments on commit 1a0d466

Please sign in to comment.