diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 8e19b3695ef49..e686e83583919 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -670,6 +670,10 @@ Bug Fixes in This Version - Correcly diagnose jumps into statement expressions. This ensures the behavior of Clang is consistent with GCC. (`#63682 `_) +- Invalidate BlockDecl with implicit return type, in case any of the return + value exprs is invalid. Propagating the error info up by replacing BlockExpr + with a RecoveryExpr. This fixes: + (`#63863 _`) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 240f1520efad2..3c9d0efca8a1e 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -17159,6 +17159,9 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, if (getCurFunction()) getCurFunction()->addBlock(BD); + if (BD->isInvalidDecl()) + return CreateRecoveryExpr(Result->getBeginLoc(), Result->getEndLoc(), + {Result}, Result->getType()); return Result; } diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 5657771a14518..70a549938d080 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -3730,6 +3730,11 @@ StmtResult Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, if (FunctionScopes.back()->FirstReturnLoc.isInvalid()) FunctionScopes.back()->FirstReturnLoc = ReturnLoc; + if (auto *CurBlock = dyn_cast(CurCap); + CurBlock && CurCap->HasImplicitReturnType && RetValExp && + RetValExp->containsErrors()) + CurBlock->TheDecl->setInvalidDecl(); + return Result; } diff --git a/clang/test/AST/ast-dump-recovery.m b/clang/test/AST/ast-dump-recovery.m index 5ca866a0282fd..c2bd078959aba 100644 --- a/clang/test/AST/ast-dump-recovery.m +++ b/clang/test/AST/ast-dump-recovery.m @@ -1,4 +1,4 @@ -// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast -frecovery-ast-type -ast-dump %s | FileCheck -strict-whitespace %s +// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast -frecovery-ast-type -fblocks -ast-dump %s | FileCheck -strict-whitespace %s @interface Foo - (void)method:(int)n; @@ -16,3 +16,11 @@ void k(Foo *foo) { // CHECK-NEXT: `-DeclRefExpr {{.*}} 'foo' foo.undef; } + +// CHECK: |-VarDecl {{.*}} 'int (^)()' cinit +// CHECK-NEXT: | `-RecoveryExpr {{.*}} ' (^)(void)' contains-errors lvalue +// CHECK-NEXT: | `-BlockExpr {{.*}} ' (^)(void)' +// CHECK-NEXT: | `-BlockDecl {{.*}} invalid +int (^gh63863)() = ^() { + return undef; +};