[clang] e1c3e16 - [clang] Fix a crash when a variable is captured by a block nested inside a lambda (#93749)

via cfe-commits cfe-commits at lists.llvm.org
Thu May 30 16:52:41 PDT 2024


Author: Akira Hatanaka
Date: 2024-05-30T16:52:37-07:00
New Revision: e1c3e16d24b5cc097ff08e9283f53319acd3f245

URL: https://github.com/llvm/llvm-project/commit/e1c3e16d24b5cc097ff08e9283f53319acd3f245
DIFF: https://github.com/llvm/llvm-project/commit/e1c3e16d24b5cc097ff08e9283f53319acd3f245.diff

LOG: [clang] Fix a crash when a variable is captured by a block nested inside a lambda (#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 https://github.com/llvm/llvm-project/issues/93625.

rdar://128482541

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/AST/Decl.cpp
    clang/test/SemaObjCXX/block-capture.mm

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f0cdccfcc3c23..594e053af02da 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -818,6 +818,7 @@ Bug Fixes to C++ Support
   Fixes (`#80252 <https://github.com/llvm/llvm-project/issues/80252>`_)
 - Fix a regression introduced in Clang 18 causing incorrect overload resolution in the presence of functions only
   
diff erering by their constraints when only one of these function was variadic.
+- Fix a crash when a variable is captured by a block nested inside a lambda. (Fixes #GH93625).
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^

diff  --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 41fbfe281ef65..0a35ed536a6a7 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2408,9 +2408,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() {

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


        


More information about the cfe-commits mailing list