Skip to content

Commit cda4a0e

Browse files
committed
[Sema] Relax a failing assertion in TransformBlockExpr
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. Differential Revision: https://reviews.llvm.org/D144016
1 parent 25a4610 commit cda4a0e

File tree

3 files changed

+27
-2
lines changed

3 files changed

+27
-2
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ Bug Fixes in This Version
141141
driver mode and emit an error which suggests using ``/TC`` or ``/TP``
142142
``clang-cl`` options instead.
143143
(`#59307 <https://github.com/llvm/llvm-project/issues/59307>`_)
144+
- Fix assert that fails when the expression causing the this pointer to be
145+
captured by a block is part of a constexpr if statement's branch and
146+
instantiation of the enclosing method causes the branch to be discarded.
144147

145148
Bug Fixes to Compiler Builtins
146149
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/TreeTransform.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14598,7 +14598,12 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
1459814598
oldCapture));
1459914599
assert(blockScope->CaptureMap.count(newCapture));
1460014600
}
14601-
assert(oldBlock->capturesCXXThis() == blockScope->isCXXThisCaptured());
14601+
14602+
// The this pointer may not be captured by the instantiated block, even when
14603+
// it's captured by the original block, if the expression causing the
14604+
// capture is in the discarded branch of a constexpr if statement.
14605+
assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
14606+
"this pointer isn't captured in the old block");
1460214607
}
1460314608
#endif
1460414609

clang/test/CodeGenCXX/cxx1z-constexpr-if.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - | FileCheck %s --implicit-check-not=should_not_be_used
1+
// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -fblocks -triple x86_64-apple-darwin10 -o - | FileCheck %s --implicit-check-not=should_not_be_used
22

33
void should_be_used_1();
44
void should_be_used_2();
@@ -32,3 +32,20 @@ foo: should_not_be_used();
3232
// CHECK: should_be_used_1
3333
// CHECK: should_be_used_2
3434
// CHECK: should_be_used_3
35+
36+
namespace BlockThisCapture {
37+
void foo();
38+
struct S {
39+
template <bool b>
40+
void m() {
41+
^{ if constexpr(b) (void)this; else foo(); }();
42+
}
43+
};
44+
45+
void test() {
46+
S().m<false>();
47+
}
48+
}
49+
50+
// CHECK-LABEL: define internal void @___ZN16BlockThisCapture1S1mILb0EEEvv_block_invoke(
51+
// CHECK: call void @_ZN16BlockThisCapture3fooEv(

0 commit comments

Comments
 (0)