jfb created this revision.
jfb added reviewers: rjmccall, ahatanak.
Herald added subscribers: cfe-commits, dexonsmith, jkorous.
Herald added a project: clang.

Capturing a C++ object by reference wasn't quite working when mixing block and 
lambda.


Repository:
  rC Clang

https://reviews.llvm.org/D58164

Files:
  lib/CodeGen/CGBlocks.cpp
  test/CodeGenCXX/lambda-capturing-block.cpp


Index: test/CodeGenCXX/lambda-capturing-block.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/lambda-capturing-block.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin -S -emit-llvm -std=c++17 
-fblocks -fcxx-exceptions -o - %s | FileCheck %s
+
+extern "C" {
+
+struct derp {
+    derp() {}
+    derp(const derp& _Src) {}
+    derp(derp&& _Src) {}
+    ~derp() {}
+    void cancel() const{}
+};
+
+// CHECK-LABEL: test(
+void test() {
+  derp c;      
+  auto b = [&](auto const& func) noexcept {
+    auto block = ^() {
+      try {
+        func();
+      } catch (...) {
+        c.cancel();
+      }
+    };
+    block();
+  };
+       
+  b([](){});
+}
+
+}
Index: lib/CodeGen/CGBlocks.cpp
===================================================================
--- lib/CodeGen/CGBlocks.cpp
+++ lib/CodeGen/CGBlocks.cpp
@@ -625,8 +625,13 @@
     } else if (CI.hasCopyExpr()) {
       info.NeedsCopyDispose = true;
       info.HasCXXObject = true;
-      if (!VT->getAsCXXRecordDecl()->isExternallyVisible())
-        info.CapturesNonExternalType = true;
+      if (auto *T = VT->getAsTagDecl()) {
+        if (T->isExternallyVisible())
+          info.CapturesNonExternalType = true;
+      } else if (auto *P = VT->getPointeeCXXRecordDecl()) {
+        if (P->isExternallyVisible())
+          info.CapturesNonExternalType = true;
+      }
 
     // So do C structs that require non-trivial copy construction or
     // destruction.


Index: test/CodeGenCXX/lambda-capturing-block.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/lambda-capturing-block.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin -S -emit-llvm -std=c++17 -fblocks -fcxx-exceptions -o - %s | FileCheck %s
+
+extern "C" {
+
+struct derp {
+    derp() {}
+    derp(const derp& _Src) {}
+    derp(derp&& _Src) {}
+    ~derp() {}
+    void cancel() const{}
+};
+
+// CHECK-LABEL: test(
+void test() {
+  derp c;	
+  auto b = [&](auto const& func) noexcept {
+    auto block = ^() {
+      try {
+        func();
+      } catch (...) {
+        c.cancel();
+      }
+    };
+    block();
+  };
+	
+  b([](){});
+}
+
+}
Index: lib/CodeGen/CGBlocks.cpp
===================================================================
--- lib/CodeGen/CGBlocks.cpp
+++ lib/CodeGen/CGBlocks.cpp
@@ -625,8 +625,13 @@
     } else if (CI.hasCopyExpr()) {
       info.NeedsCopyDispose = true;
       info.HasCXXObject = true;
-      if (!VT->getAsCXXRecordDecl()->isExternallyVisible())
-        info.CapturesNonExternalType = true;
+      if (auto *T = VT->getAsTagDecl()) {
+        if (T->isExternallyVisible())
+          info.CapturesNonExternalType = true;
+      } else if (auto *P = VT->getPointeeCXXRecordDecl()) {
+        if (P->isExternallyVisible())
+          info.CapturesNonExternalType = true;
+      }
 
     // So do C structs that require non-trivial copy construction or
     // destruction.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to