Skip to content

Commit 3153a10

Browse files
authored
Merge pull request #2968 from Teemperor/cherry/888ce70af288168136cf1ca658c3cf6d6759bb3f
[DebugInfo] Fix DWARF expressions for __block vars that are not on th…
2 parents 1685df8 + 28e7e9c commit 3153a10

File tree

2 files changed

+53
-5
lines changed

2 files changed

+53
-5
lines changed

clang/lib/CodeGen/CGDebugInfo.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4231,7 +4231,9 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
42314231
auto *Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
42324232
StringRef Name = VD->getName();
42334233
if (!Name.empty()) {
4234-
if (VD->hasAttr<BlocksAttr>()) {
4234+
// __block vars are stored on the heap if they are captured by a block that
4235+
// can escape the local scope.
4236+
if (VD->isEscapingByref()) {
42354237
// Here, we need an offset *into* the alloca.
42364238
CharUnits offset = CharUnits::fromQuantity(32);
42374239
Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,55 @@
11
// RUN: %clang_cc1 -fblocks -debug-info-kind=limited -emit-llvm -o - %s | FileCheck %s
2+
// RUN: %clang_cc1 -DDEAD_CODE -fblocks -debug-info-kind=limited -emit-llvm -o - %s | FileCheck %s
3+
4+
typedef void (^BlockTy)();
5+
void escapeFunc(BlockTy);
6+
typedef void (^BlockTy)();
7+
void noEscapeFunc(__attribute__((noescape)) BlockTy);
8+
9+
// Verify that the desired DIExpression are generated for escaping (i.e, not
10+
// 'noescape') blocks.
11+
void test_escape_func() {
12+
// CHECK-LABEL: void @test_escape_func
13+
// CHECK: call void @llvm.dbg.declare({{.*}}metadata ![[ESCAPE_VAR:[0-9]+]], metadata !DIExpression(DW_OP_plus_uconst, {{[0-9]+}}, DW_OP_deref, DW_OP_plus_uconst, {{[0-9]+}}){{.*}})
14+
__block int escape_var;
15+
// Blocks in dead code branches still capture __block variables.
16+
#ifdef DEAD_CODE
17+
if (0)
18+
#endif
19+
escapeFunc(^{ (void)escape_var; });
20+
}
21+
22+
// Verify that the desired DIExpression are generated for noescape blocks.
23+
void test_noescape_func() {
24+
// CHECK-LABEL: void @test_noescape_func
25+
// CHECK: call void @llvm.dbg.declare({{.*}}metadata ![[NOESCAPE_VAR:[0-9]+]], metadata !DIExpression())
26+
__block int noescape_var;
27+
noEscapeFunc(^{ (void)noescape_var; });
28+
}
29+
230
// Verify that the desired DIExpression are generated for blocks.
31+
void test_local_block() {
32+
// CHECK-LABEL: void @test_local_block
33+
// CHECK: call void @llvm.dbg.declare({{.*}}metadata ![[BLOCK_VAR:[0-9]+]], metadata !DIExpression(DW_OP_plus_uconst, {{[0-9]+}}, DW_OP_deref, DW_OP_plus_uconst, {{[0-9]+}}){{.*}})
34+
__block int block_var;
335

4-
void test() {
5-
// CHECK: call void @llvm.dbg.declare({{.*}}!DIExpression(DW_OP_plus_uconst, {{[0-9]+}}, DW_OP_deref, DW_OP_plus_uconst, {{[0-9]+}}){{.*}})
6-
__block int i;
36+
// CHECK-LABEL: @__test_local_block_block_invoke
737
// CHECK: call void @llvm.dbg.declare({{.*}}!DIExpression(DW_OP_deref, DW_OP_plus_uconst, {{[0-9]+}}, DW_OP_deref, DW_OP_plus_uconst, {{[0-9]+}}, DW_OP_deref, DW_OP_plus_uconst, {{[0-9]+}}){{.*}})
8-
^ { i = 1; }();
38+
^ { block_var = 1; }();
39+
}
40+
41+
// Verify that the desired DIExpression are generated for __block vars not used
42+
// in any block.
43+
void test_unused() {
44+
// CHECK-LABEL: void @test_unused
45+
// CHECK: call void @llvm.dbg.declare({{.*}}metadata ![[UNUSED_VAR:[0-9]+]], metadata !DIExpression())
46+
__block int unused_var;
47+
// Use i (not inside a block).
48+
++unused_var;
949
}
50+
51+
// CHECK: ![[ESCAPE_VAR]] = !DILocalVariable(name: "escape_var"
52+
// CHECK: ![[NOESCAPE_VAR]] = !DILocalVariable(name: "noescape_var"
53+
// CHECK: ![[BLOCK_VAR]] = !DILocalVariable(name: "block_var"
54+
// CHECK: ![[UNUSED_VAR]] = !DILocalVariable(name: "unused_var"
55+

0 commit comments

Comments
 (0)