ahatanak created this revision.
ahatanak added reviewers: arphaman, fahad, aaron.ballman.
ahatanak added a project: clang.
Herald added a project: All.
ahatanak requested review of this revision.

The assertion fails when the expression causing the this pointer to be captured 
is part of a constexpr if statement's branch and the branch gets discarded when 
the enclosing method is instantiated.

Note that the test case is added to CodeGen instead of Sema since the 
translation unit has to be free of errors in order for the assertion to be 
checked.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D144016

Files:
  clang/lib/Sema/TreeTransform.h
  clang/test/CodeGenCXX/cxx1z-constexpr-if.cpp


Index: clang/test/CodeGenCXX/cxx1z-constexpr-if.cpp
===================================================================
--- clang/test/CodeGenCXX/cxx1z-constexpr-if.cpp
+++ clang/test/CodeGenCXX/cxx1z-constexpr-if.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - | FileCheck %s 
--implicit-check-not=should_not_be_used
+// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -fblocks -o - | FileCheck %s 
--implicit-check-not=should_not_be_used
 
 void should_be_used_1();
 void should_be_used_2();
@@ -32,3 +32,20 @@
 // CHECK: should_be_used_1
 // CHECK: should_be_used_2
 // CHECK: should_be_used_3
+
+namespace BlockThisCapture {
+  void foo();
+  struct S {
+    template <bool b>
+    void m() {
+      ^{ if constexpr(b) (void)this; else foo();  }();
+    }
+  };
+
+  void test() {
+    S().m<false>();
+  }
+}
+
+// CHECK-LABEL: define internal void 
@___ZN16BlockThisCapture1S1mILb0EEEvv_block_invoke(
+// CHECK: call void @_ZN16BlockThisCapture3fooEv(
Index: clang/lib/Sema/TreeTransform.h
===================================================================
--- clang/lib/Sema/TreeTransform.h
+++ clang/lib/Sema/TreeTransform.h
@@ -14598,7 +14598,8 @@
                                                  oldCapture));
       assert(blockScope->CaptureMap.count(newCapture));
     }
-    assert(oldBlock->capturesCXXThis() == blockScope->isCXXThisCaptured());
+    assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
+           "this pointer isn't captured in the old block");
   }
 #endif
 


Index: clang/test/CodeGenCXX/cxx1z-constexpr-if.cpp
===================================================================
--- clang/test/CodeGenCXX/cxx1z-constexpr-if.cpp
+++ clang/test/CodeGenCXX/cxx1z-constexpr-if.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - | FileCheck %s --implicit-check-not=should_not_be_used
+// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -fblocks -o - | FileCheck %s --implicit-check-not=should_not_be_used
 
 void should_be_used_1();
 void should_be_used_2();
@@ -32,3 +32,20 @@
 // CHECK: should_be_used_1
 // CHECK: should_be_used_2
 // CHECK: should_be_used_3
+
+namespace BlockThisCapture {
+  void foo();
+  struct S {
+    template <bool b>
+    void m() {
+      ^{ if constexpr(b) (void)this; else foo();  }();
+    }
+  };
+
+  void test() {
+    S().m<false>();
+  }
+}
+
+// CHECK-LABEL: define internal void @___ZN16BlockThisCapture1S1mILb0EEEvv_block_invoke(
+// CHECK: call void @_ZN16BlockThisCapture3fooEv(
Index: clang/lib/Sema/TreeTransform.h
===================================================================
--- clang/lib/Sema/TreeTransform.h
+++ clang/lib/Sema/TreeTransform.h
@@ -14598,7 +14598,8 @@
                                                  oldCapture));
       assert(blockScope->CaptureMap.count(newCapture));
     }
-    assert(oldBlock->capturesCXXThis() == blockScope->isCXXThisCaptured());
+    assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
+           "this pointer isn't captured in the old block");
   }
 #endif
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to