Skip to content

Commit 4140a68

Browse files
authored
[Sema] Relax a failing assertion in TransformBlockExpr (#6298)
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 (cherry picked from commit cda4a0e) Conflicts: clang/docs/ReleaseNotes.rst
1 parent 9e253b8 commit 4140a68

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
@@ -271,6 +271,9 @@ Bug Fixes
271271
`Issue 59100 <https://github.com/llvm/llvm-project/issues/59100>`_
272272
- Fix issue using __attribute__((format)) on non-variadic functions that expect
273273
more than one formatted argument.
274+
- Fix assert that fails when the expression causing the this pointer to be
275+
captured by a block is part of a constexpr if statement's branch and
276+
instantiation of the enclosing method causes the branch to be discarded.
274277

275278
Improvements to Clang's diagnostics
276279
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/TreeTransform.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14439,7 +14439,12 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
1443914439
oldCapture));
1444014440
assert(blockScope->CaptureMap.count(newCapture));
1444114441
}
14442-
assert(oldBlock->capturesCXXThis() == blockScope->isCXXThisCaptured());
14442+
14443+
// The this pointer may not be captured by the instantiated block, even when
14444+
// it's captured by the original block, if the expression causing the
14445+
// capture is in the discarded branch of a constexpr if statement.
14446+
assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
14447+
"this pointer isn't captured in the old block");
1444314448
}
1444414449
#endif
1444514450

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)