Skip to content

Commit

Permalink
[Sema][ObjC] Invalidate BlockDecl with invalid return expr & its pare…
Browse files Browse the repository at this point in the history
…nt 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
  • Loading branch information
danix800 committed Jul 24, 2023
1 parent 2f1244c commit 106bde9
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 1 deletion.
4 changes: 4 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 <https://github.com/llvm/llvm-project/issues/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 <https://github.com/llvm/llvm-project/issues/63863>_`)

Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Sema/SemaStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3730,6 +3730,11 @@ StmtResult Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc,
if (FunctionScopes.back()->FirstReturnLoc.isInvalid())
FunctionScopes.back()->FirstReturnLoc = ReturnLoc;

if (auto *CurBlock = dyn_cast<BlockScopeInfo>(CurCap);
CurBlock && CurCap->HasImplicitReturnType && RetValExp &&
RetValExp->containsErrors())
CurBlock->TheDecl->setInvalidDecl();

return Result;
}

Expand Down
10 changes: 9 additions & 1 deletion clang/test/AST/ast-dump-recovery.m
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -16,3 +16,11 @@ void k(Foo *foo) {
// CHECK-NEXT: `-DeclRefExpr {{.*}} 'foo'
foo.undef;
}

// CHECK: |-VarDecl {{.*}} 'int (^)()' cinit
// CHECK-NEXT: | `-RecoveryExpr {{.*}} '<dependent type> (^)(void)' contains-errors lvalue
// CHECK-NEXT: | `-BlockExpr {{.*}} '<dependent type> (^)(void)'
// CHECK-NEXT: | `-BlockDecl {{.*}} invalid
int (^gh63863)() = ^() {
return undef;
};

0 comments on commit 106bde9

Please sign in to comment.