Skip to content

Commit 106bde9

Browse files
committed
[Sema][ObjC] Invalidate BlockDecl with invalid return expr & its parent BlockExpr
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. The idea of this fix is given by @hokein(Haojian Wu) Fix #63863. Differential Revision: https://reviews.llvm.org/D155396
1 parent 2f1244c commit 106bde9

File tree

4 files changed

+21
-1
lines changed

4 files changed

+21
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,10 @@ Bug Fixes in This Version
670670
- Correcly diagnose jumps into statement expressions.
671671
This ensures the behavior of Clang is consistent with GCC.
672672
(`#63682 <https://github.com/llvm/llvm-project/issues/63682>`_)
673+
- Invalidate BlockDecl with implicit return type, in case any of the return
674+
value exprs is invalid. Propagating the error info up by replacing BlockExpr
675+
with a RecoveryExpr. This fixes:
676+
(`#63863 <https://github.com/llvm/llvm-project/issues/63863>_`)
673677

674678
Bug Fixes to Compiler Builtins
675679
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaExpr.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17159,6 +17159,9 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
1715917159
if (getCurFunction())
1716017160
getCurFunction()->addBlock(BD);
1716117161

17162+
if (BD->isInvalidDecl())
17163+
return CreateRecoveryExpr(Result->getBeginLoc(), Result->getEndLoc(),
17164+
{Result}, Result->getType());
1716217165
return Result;
1716317166
}
1716417167

clang/lib/Sema/SemaStmt.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3730,6 +3730,11 @@ StmtResult Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc,
37303730
if (FunctionScopes.back()->FirstReturnLoc.isInvalid())
37313731
FunctionScopes.back()->FirstReturnLoc = ReturnLoc;
37323732

3733+
if (auto *CurBlock = dyn_cast<BlockScopeInfo>(CurCap);
3734+
CurBlock && CurCap->HasImplicitReturnType && RetValExp &&
3735+
RetValExp->containsErrors())
3736+
CurBlock->TheDecl->setInvalidDecl();
3737+
37333738
return Result;
37343739
}
37353740

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast -frecovery-ast-type -ast-dump %s | FileCheck -strict-whitespace %s
1+
// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast -frecovery-ast-type -fblocks -ast-dump %s | FileCheck -strict-whitespace %s
22

33
@interface Foo
44
- (void)method:(int)n;
@@ -16,3 +16,11 @@ void k(Foo *foo) {
1616
// CHECK-NEXT: `-DeclRefExpr {{.*}} 'foo'
1717
foo.undef;
1818
}
19+
20+
// CHECK: |-VarDecl {{.*}} 'int (^)()' cinit
21+
// CHECK-NEXT: | `-RecoveryExpr {{.*}} '<dependent type> (^)(void)' contains-errors lvalue
22+
// CHECK-NEXT: | `-BlockExpr {{.*}} '<dependent type> (^)(void)'
23+
// CHECK-NEXT: | `-BlockDecl {{.*}} invalid
24+
int (^gh63863)() = ^() {
25+
return undef;
26+
};

0 commit comments

Comments
 (0)