diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1389,6 +1389,9 @@ if (!Result.isInvalid() && Result.get()->isInstantiationDependent() && !Result.get()->isTypeDependent()) Result = CorrectDelayedTyposInExpr(Result.get()); + if (Result.isInvalid()) + return CreateRecoveryExpr(TInfo->getTypeLoc().getBeginLoc(), + RParenOrBraceLoc, exprs, Ty); return Result; } diff --git a/clang/test/AST/ast-dump-recovery.cpp b/clang/test/AST/ast-dump-recovery.cpp --- a/clang/test/AST/ast-dump-recovery.cpp +++ b/clang/test/AST/ast-dump-recovery.cpp @@ -159,11 +159,18 @@ // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors // CHECK-NEXT: `-InitListExpr Bar b2 = {1}; - // FIXME: preserve the invalid initializer. - // CHECK: `-VarDecl {{.*}} b3 'Bar' + // CHECK: `-VarDecl {{.*}} b3 'Bar' + // CHECK-NEXT: `-CXXConstructExpr {{.*}} 'Bar' contains-errors + // CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'const Bar' contains-errors + // CHECK-NEXT: `-RecoveryExpr {{.*}} 'Bar' contains-errors lvalue + // CHECK-NEXT: `-DeclRefExpr {{.*}} 'x' 'int' Bar b3 = Bar(x); - // FIXME: preserve the invalid initializer. - // CHECK: `-VarDecl {{.*}} b4 'Bar' + // CHECK: `-VarDecl {{.*}} b4 'Bar' + // CHECK-NEXT: `-CXXConstructExpr {{.*}} 'Bar' contains-errors + // CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'const Bar' contains-errors + // CHECK-NEXT: `-RecoveryExpr {{.*}} 'Bar' contains-errors + // CHECK-NEXT: `-InitListExpr {{.*}} 'void' + // CHECK-NEXT: `-DeclRefExpr {{.*}} 'x' 'int' Bar b4 = Bar{x}; // CHECK: `-VarDecl {{.*}} b5 'Bar' // CHECK-NEXT: `-CXXUnresolvedConstructExpr {{.*}} 'Bar' contains-errors 'Bar' @@ -176,6 +183,10 @@ // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors // CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'invalid' Bar b6 = Bar{invalid()}; + + // CHECK: `-RecoveryExpr {{.*}} 'Bar' contains-errors + // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1 + Bar(1); } void InitializerForAuto() { // CHECK: `-VarDecl {{.*}} invalid a 'auto'