This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG888ce70af288: [DebugInfo] Fix DWARF expressions for __block vars that are not on the heap (authored by teemperor). Herald added a subscriber: cfe-commits.
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D99946/new/ https://reviews.llvm.org/D99946 Files: clang/lib/CodeGen/CGDebugInfo.cpp clang/test/CodeGen/debug-info-block-expr.c Index: clang/test/CodeGen/debug-info-block-expr.c =================================================================== --- clang/test/CodeGen/debug-info-block-expr.c +++ clang/test/CodeGen/debug-info-block-expr.c @@ -1,9 +1,55 @@ // RUN: %clang_cc1 -fblocks -debug-info-kind=limited -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DDEAD_CODE -fblocks -debug-info-kind=limited -emit-llvm -o - %s | FileCheck %s + +typedef void (^BlockTy)(); +void escapeFunc(BlockTy); +typedef void (^BlockTy)(); +void noEscapeFunc(__attribute__((noescape)) BlockTy); + +// Verify that the desired DIExpression are generated for escaping (i.e, not +// 'noescape') blocks. +void test_escape_func() { +// CHECK-LABEL: void @test_escape_func +// 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]+}}){{.*}}) + __block int escape_var; +// Blocks in dead code branches still capture __block variables. +#ifdef DEAD_CODE + if (0) +#endif + escapeFunc(^{ (void)escape_var; }); +} + +// Verify that the desired DIExpression are generated for noescape blocks. +void test_noescape_func() { +// CHECK-LABEL: void @test_noescape_func +// CHECK: call void @llvm.dbg.declare({{.*}}metadata ![[NOESCAPE_VAR:[0-9]+]], metadata !DIExpression()) + __block int noescape_var; + noEscapeFunc(^{ (void)noescape_var; }); +} + // Verify that the desired DIExpression are generated for blocks. +void test_local_block() { +// CHECK-LABEL: void @test_local_block +// 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]+}}){{.*}}) + __block int block_var; -void test() { -// CHECK: call void @llvm.dbg.declare({{.*}}!DIExpression(DW_OP_plus_uconst, {{[0-9]+}}, DW_OP_deref, DW_OP_plus_uconst, {{[0-9]+}}){{.*}}) - __block int i; +// CHECK-LABEL: @__test_local_block_block_invoke // 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]+}}){{.*}}) - ^ { i = 1; }(); + ^ { block_var = 1; }(); +} + +// Verify that the desired DIExpression are generated for __block vars not used +// in any block. +void test_unused() { +// CHECK-LABEL: void @test_unused +// CHECK: call void @llvm.dbg.declare({{.*}}metadata ![[UNUSED_VAR:[0-9]+]], metadata !DIExpression()) + __block int unused_var; +// Use i (not inside a block). + ++unused_var; } + +// CHECK: ![[ESCAPE_VAR]] = !DILocalVariable(name: "escape_var" +// CHECK: ![[NOESCAPE_VAR]] = !DILocalVariable(name: "noescape_var" +// CHECK: ![[BLOCK_VAR]] = !DILocalVariable(name: "block_var" +// CHECK: ![[UNUSED_VAR]] = !DILocalVariable(name: "unused_var" + Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -4303,7 +4303,9 @@ auto *Scope = cast<llvm::DIScope>(LexicalBlockStack.back()); StringRef Name = VD->getName(); if (!Name.empty()) { - if (VD->hasAttr<BlocksAttr>()) { + // __block vars are stored on the heap if they are captured by a block that + // can escape the local scope. + if (VD->isEscapingByref()) { // Here, we need an offset *into* the alloca. CharUnits offset = CharUnits::fromQuantity(32); Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
Index: clang/test/CodeGen/debug-info-block-expr.c =================================================================== --- clang/test/CodeGen/debug-info-block-expr.c +++ clang/test/CodeGen/debug-info-block-expr.c @@ -1,9 +1,55 @@ // RUN: %clang_cc1 -fblocks -debug-info-kind=limited -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DDEAD_CODE -fblocks -debug-info-kind=limited -emit-llvm -o - %s | FileCheck %s + +typedef void (^BlockTy)(); +void escapeFunc(BlockTy); +typedef void (^BlockTy)(); +void noEscapeFunc(__attribute__((noescape)) BlockTy); + +// Verify that the desired DIExpression are generated for escaping (i.e, not +// 'noescape') blocks. +void test_escape_func() { +// CHECK-LABEL: void @test_escape_func +// 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]+}}){{.*}}) + __block int escape_var; +// Blocks in dead code branches still capture __block variables. +#ifdef DEAD_CODE + if (0) +#endif + escapeFunc(^{ (void)escape_var; }); +} + +// Verify that the desired DIExpression are generated for noescape blocks. +void test_noescape_func() { +// CHECK-LABEL: void @test_noescape_func +// CHECK: call void @llvm.dbg.declare({{.*}}metadata ![[NOESCAPE_VAR:[0-9]+]], metadata !DIExpression()) + __block int noescape_var; + noEscapeFunc(^{ (void)noescape_var; }); +} + // Verify that the desired DIExpression are generated for blocks. +void test_local_block() { +// CHECK-LABEL: void @test_local_block +// 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]+}}){{.*}}) + __block int block_var; -void test() { -// CHECK: call void @llvm.dbg.declare({{.*}}!DIExpression(DW_OP_plus_uconst, {{[0-9]+}}, DW_OP_deref, DW_OP_plus_uconst, {{[0-9]+}}){{.*}}) - __block int i; +// CHECK-LABEL: @__test_local_block_block_invoke // 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]+}}){{.*}}) - ^ { i = 1; }(); + ^ { block_var = 1; }(); +} + +// Verify that the desired DIExpression are generated for __block vars not used +// in any block. +void test_unused() { +// CHECK-LABEL: void @test_unused +// CHECK: call void @llvm.dbg.declare({{.*}}metadata ![[UNUSED_VAR:[0-9]+]], metadata !DIExpression()) + __block int unused_var; +// Use i (not inside a block). + ++unused_var; } + +// CHECK: ![[ESCAPE_VAR]] = !DILocalVariable(name: "escape_var" +// CHECK: ![[NOESCAPE_VAR]] = !DILocalVariable(name: "noescape_var" +// CHECK: ![[BLOCK_VAR]] = !DILocalVariable(name: "block_var" +// CHECK: ![[UNUSED_VAR]] = !DILocalVariable(name: "unused_var" + Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -4303,7 +4303,9 @@ auto *Scope = cast<llvm::DIScope>(LexicalBlockStack.back()); StringRef Name = VD->getName(); if (!Name.empty()) { - if (VD->hasAttr<BlocksAttr>()) { + // __block vars are stored on the heap if they are captured by a block that + // can escape the local scope. + if (VD->isEscapingByref()) { // Here, we need an offset *into* the alloca. CharUnits offset = CharUnits::fromQuantity(32); Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits