Skip to content

Commit

Permalink
[clang] Fix a crash when a variable is captured by a block nested ins…
Browse files Browse the repository at this point in the history
…ide a lambda (llvm#93749)

`Eval->Value.get` returns a null pointer when the variable doesn't have
an initializer. Use `cast_if_present` instead of `cast`.

This fixes llvm#93625.

rdar://128482541
(cherry picked from commit e1c3e16)

Conflicts:
	clang/docs/ReleaseNotes.rst
  • Loading branch information
ahatanak authored and ahatanaka committed May 30, 2024
1 parent cc2834b commit fa37db0
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 3 deletions.
1 change: 1 addition & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,7 @@ Bug Fixes to C++ Support
- Fix crash when inheriting from a cv-qualified type. Fixes:
(`#35603 <https://github.com/llvm/llvm-project/issues/35603>`_)
- Fix a crash when the using enum declaration uses an anonymous enumeration. Fixes (#GH86790).
- Fix a crash when a variable is captured by a block nested inside a lambda. (Fixes #GH93625).

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
8 changes: 5 additions & 3 deletions clang/lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2409,9 +2409,11 @@ Expr *VarDecl::getInit() {
return cast<Expr>(S);

auto *Eval = getEvaluatedStmt();
return cast<Expr>(Eval->Value.isOffset()
? Eval->Value.get(getASTContext().getExternalSource())
: Eval->Value.get(nullptr));

return cast_if_present<Expr>(
Eval->Value.isOffset()
? Eval->Value.get(getASTContext().getExternalSource())
: Eval->Value.get(nullptr));
}

Stmt **VarDecl::getInitAddress() {
Expand Down
18 changes: 18 additions & 0 deletions clang/test/SemaObjCXX/block-capture.mm
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,21 @@
SubMove(SubSubMove &&);
};
TEST(SubMove);


#if __cplusplus >= 202302L
// clang used to crash compiling this code.
namespace BlockInLambda {
struct S {
constexpr ~S();
};

void func(S const &a) {
[a](auto b) {
^{
(void)a;
}();
}(12);
}
}
#endif

0 comments on commit fa37db0

Please sign in to comment.