Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -4292,7 +4292,9 @@ auto *Scope = cast(LexicalBlockStack.back()); StringRef Name = VD->getName(); if (!Name.empty()) { - if (VD->hasAttr()) { + // __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-escape-func.c =================================================================== --- /dev/null +++ clang/test/CodeGen/debug-info-block-expr-escape-func.c @@ -0,0 +1,21 @@ +// Verify that the desired DIExpression are generated for escaping (i.e, not +// 'noescape') blocks. + +// 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); + +void test() { +// CHECK-LABEL: void @test +// CHECK: call void @llvm.dbg.declare({{.*}}!DIExpression(DW_OP_plus_uconst, {{[0-9]+}}, DW_OP_deref, DW_OP_plus_uconst, {{[0-9]+}}){{.*}}) +// Prevent accidential passes due to DIExpressions() in the block init code. +// CHECK-LABEL: %byref.isa = + __block int i; +// Blocks in dead code branches still capture __block variables. +#ifdef DEAD_CODE + if (0) +#endif + escapeFunc(^{ (void)i; }); +} Index: clang/test/CodeGen/debug-info-block-expr-noescape-func.c =================================================================== --- /dev/null +++ clang/test/CodeGen/debug-info-block-expr-noescape-func.c @@ -0,0 +1,15 @@ +// Verify that the desired DIExpression are generated for noescape blocks. + +// RUN: %clang_cc1 -fblocks -debug-info-kind=limited -emit-llvm -o - %s | FileCheck %s + +typedef void (^BlockTy)(); +void noEscapeFunc(__attribute__((noescape)) BlockTy); + +void test() { +// CHECK-LABEL: void @test +// CHECK: call void @llvm.dbg.declare({{.*}}!DIExpression()) +// Prevent accidential passes due to DIExpressions() in the block init code. +// CHECK-LABEL: %block.isa = + __block int i; + noEscapeFunc(^{ (void)i; }); +} Index: clang/test/CodeGen/debug-info-block-expr-unused.c =================================================================== --- /dev/null +++ clang/test/CodeGen/debug-info-block-expr-unused.c @@ -0,0 +1,18 @@ +// Verify that the desired DIExpression are generated for __block vars not used +// in any block. + +// RUN: %clang_cc1 -fblocks -debug-info-kind=limited -emit-llvm -o - %s | FileCheck %s + +typedef void (^BlockTy)(); +void noEscapeFunc(__attribute__((noescape)) BlockTy); + +int test() { +// CHECK-LABEL: i32 @test +// CHECK: call void @llvm.dbg.declare({{.*}}!DIExpression()) + __block int i; +// Use i (not inside a block). + ++i; +// Prevent accidential passes due to DIExpressions() in the block init code. +// CHECK-LABEL: ret i32 1234 + return 1234; +}