From 4648f46f5e15d5747596347feaef85069a8ce4df Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Wed, 29 May 2024 15:19:58 -0700 Subject: [PATCH 1/3] Use cast_or_null instead of cast `Eval->Value.get` returns a null pointer when the variable doesn't have an initializer. This fixes https://github.com/llvm/llvm-project/issues/93625. rdar://128482541 --- clang/lib/AST/Decl.cpp | 8 +++++--- clang/test/SemaObjCXX/block-capture.mm | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 41fbfe281ef65..4940a787e7d30 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2408,9 +2408,11 @@ Expr *VarDecl::getInit() { return cast(S); auto *Eval = getEvaluatedStmt(); - return cast(Eval->Value.isOffset() - ? Eval->Value.get(getASTContext().getExternalSource()) - : Eval->Value.get(nullptr)); + + return cast_or_null( + Eval->Value.isOffset() + ? Eval->Value.get(getASTContext().getExternalSource()) + : Eval->Value.get(nullptr)); } Stmt **VarDecl::getInitAddress() { diff --git a/clang/test/SemaObjCXX/block-capture.mm b/clang/test/SemaObjCXX/block-capture.mm index 8ba02f919e015..231aef33f2c7e 100644 --- a/clang/test/SemaObjCXX/block-capture.mm +++ b/clang/test/SemaObjCXX/block-capture.mm @@ -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 From de2bd511b5dcd683b762b7bc68f8628de30f3341 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Thu, 30 May 2024 09:12:49 -0700 Subject: [PATCH 2/3] Use cast_if_present --- clang/lib/AST/Decl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 4940a787e7d30..0a35ed536a6a7 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2409,7 +2409,7 @@ Expr *VarDecl::getInit() { auto *Eval = getEvaluatedStmt(); - return cast_or_null( + return cast_if_present( Eval->Value.isOffset() ? Eval->Value.get(getASTContext().getExternalSource()) : Eval->Value.get(nullptr)); From 23908d596741b271feb70feb6291bc5b8a5ed97b Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Thu, 30 May 2024 10:06:47 -0700 Subject: [PATCH 3/3] Add an entry in release note --- clang/docs/ReleaseNotes.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 44035f48cb3f9..0d9e4b8aba500 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -813,6 +813,7 @@ Bug Fixes to C++ Support - Clang now allows ``@$``` in raw string literals. Fixes (#GH93130). - Fix an assertion failure when checking invalid ``this`` usage in the wrong context. (Fixes #GH91536). - Clang no longer models dependent NTTP arguments as ``TemplateParamObjectDecl`` s. Fixes (#GH84052). +- Fix a crash when a variable is captured by a block nested inside a lambda. (Fixes #GH93625). Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^