[clang] [Clang][DebugInfo] Clang generates an extra spurious unnamed 'dbg.declare' (PR #69681)

Carlos Alberto Enciso via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 25 01:47:32 PDT 2023


https://github.com/CarlosAlbertoEnciso updated https://github.com/llvm/llvm-project/pull/69681

>From 42df544996bb8fee93e5d1bab72e71578645bcc4 Mon Sep 17 00:00:00 2001
From: Carlos Alberto Enciso <carlos.alberto.enciso at gmail.com>
Date: Fri, 20 Oct 2023 06:09:04 +0100
Subject: [PATCH 1/3] [Clang][DebugInfo] Clang generates an extra spurious
 unnamed 'dbg.declare'.

Do not emit call to llvm.dbg.declare when the variable declaration
is a DecompositionDecl as its instance class is always unnamed.

The emitted debug declare looks like:

  call void @llvm.dbg.declare(metadata ..., metadata !xx, metadata ...)
  !xx = !DILocalVariable(scope: !..., file: !..., line: ..., type: !...)
---
 clang/lib/CodeGen/CGDebugInfo.cpp             |  6 +++++-
 ...debug-info-structured-binding-bitfield.cpp |  3 ---
 .../debug-info-structured-binding-field.cpp   | 20 +++++++++++++++++++
 .../debug-info-structured-binding.cpp         |  2 --
 4 files changed, 25 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/CodeGenCXX/debug-info-structured-binding-field.cpp

diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 181e500b9671759..0aaf678bf287c6e 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -4881,11 +4881,15 @@ CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *VD, llvm::Value *Storage,
                                        const bool UsePointerValue) {
   assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
 
-  if (auto *DD = dyn_cast<DecompositionDecl>(VD))
+  if (auto *DD = dyn_cast<DecompositionDecl>(VD)) {
     for (auto *B : DD->bindings()) {
       EmitDeclare(B, Storage, std::nullopt, Builder,
                   VD->getType()->isReferenceType());
     }
+    // Don't emit an llvm.dbg.declare for the composite storage as it doesn't
+    // correspond to a user variable.
+    return nullptr;
+  }
 
   return EmitDeclare(VD, Storage, std::nullopt, Builder, UsePointerValue);
 }
diff --git a/clang/test/CodeGenCXX/debug-info-structured-binding-bitfield.cpp b/clang/test/CodeGenCXX/debug-info-structured-binding-bitfield.cpp
index b5ee96224565d3a..0234e41009f6225 100644
--- a/clang/test/CodeGenCXX/debug-info-structured-binding-bitfield.cpp
+++ b/clang/test/CodeGenCXX/debug-info-structured-binding-bitfield.cpp
@@ -189,7 +189,6 @@ struct S11 {
 // CHECK-LABEL: define dso_local void @_Z4fS11v
 // CHECK:                        alloca %struct.S11, align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = alloca %struct.S11, align 4
-// CHECK:         call void @llvm.dbg.declare(metadata ptr [[TMP0]]
 // CHECK-NOT:     call void @llvm.dbg.declare(metadata ptr [[TMP0]]
 //
 void fS11() {
@@ -206,7 +205,6 @@ struct S12 {
 // CHECK:                        alloca %struct.S12, align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = alloca %struct.S12, align 4
 // CHECK:         call void @llvm.dbg.declare(metadata ptr [[TMP0]], metadata [[S12_A:![0-9]+]], metadata !DIExpression())
-// CHECK:         call void @llvm.dbg.declare(metadata ptr [[TMP0]]
 // CHECK-NOT:     call void @llvm.dbg.declare(metadata ptr [[TMP0]]
 //
 void fS12() {
@@ -222,7 +220,6 @@ struct __attribute__((packed)) S13 {
 // CHECK-LABEL: define dso_local void @_Z4fS13v
 // CHECK:                        alloca %struct.S13, align 1
 // CHECK-NEXT:    [[TMP0:%.*]] = alloca %struct.S13, align 1
-// CHECK:         call void @llvm.dbg.declare(metadata ptr [[TMP0]], metadata {{.*}}, metadata !DIExpression())
 // CHECK-NOT:     call void @llvm.dbg.declare(metadata ptr [[TMP0]]
 //
 void fS13() {
diff --git a/clang/test/CodeGenCXX/debug-info-structured-binding-field.cpp b/clang/test/CodeGenCXX/debug-info-structured-binding-field.cpp
new file mode 100644
index 000000000000000..928d22776d21093
--- /dev/null
+++ b/clang/test/CodeGenCXX/debug-info-structured-binding-field.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s
+
+struct Tuple {
+  int Fld_1;
+  int Fld_2;
+};
+__attribute__((optnone)) Tuple get() { return {10, 20}; }
+
+// CHECK-LABEL: define dso_local noundef i32 @main
+// CHECK:      %retval = alloca i32, align 4
+// CHECK-NEXT: [[T0:%.*]] = alloca %struct.Tuple, align 4
+// CHECK:      call void @llvm.dbg.declare(metadata ptr [[T0]], metadata {{.*}}, metadata !DIExpression())
+// CHECK:      call void @llvm.dbg.declare(metadata ptr [[T0]], metadata {{.*}}, metadata !DIExpression(DW_OP_plus_uconst, {{[0-9]+}}))
+// CHECK-NOT:  call void @llvm.dbg.declare(metadata ptr [[T0]], metadata {{.*}}, metadata !DIExpression())
+//
+int main() {
+  auto [Var_1, Var_2] = get();
+
+  return Var_1 + Var_2;
+}
diff --git a/clang/test/CodeGenCXX/debug-info-structured-binding.cpp b/clang/test/CodeGenCXX/debug-info-structured-binding.cpp
index 8d4ae0aaf32636b..163c152efa19d0b 100644
--- a/clang/test/CodeGenCXX/debug-info-structured-binding.cpp
+++ b/clang/test/CodeGenCXX/debug-info-structured-binding.cpp
@@ -2,10 +2,8 @@
 
 // CHECK: call void @llvm.dbg.declare(metadata ptr %{{[0-9]+}}, metadata !{{[0-9]+}}, metadata !DIExpression())
 // CHECK: call void @llvm.dbg.declare(metadata ptr %{{[0-9]+}}, metadata !{{[0-9]+}}, metadata !DIExpression(DW_OP_plus_uconst, {{[0-9]+}}))
-// CHECK: call void @llvm.dbg.declare(metadata ptr %{{[0-9]+}}, metadata !{{[0-9]+}}, metadata !DIExpression())
 // CHECK: call void @llvm.dbg.declare(metadata ptr %{{[0-9]+}}, metadata !{{[0-9]+}}, metadata !DIExpression(DW_OP_deref))
 // CHECK: call void @llvm.dbg.declare(metadata ptr %{{[0-9]+}}, metadata !{{[0-9]+}}, metadata !DIExpression(DW_OP_deref, DW_OP_plus_uconst, {{[0-9]+}}))
-// CHECK: call void @llvm.dbg.declare(metadata ptr %{{[0-9]+}}, metadata !{{[0-9]+}}, metadata !DIExpression())
 struct A {
   int x;
   int y;

>From f75acae4f7c27d14418098b516f5359cbd055e53 Mon Sep 17 00:00:00 2001
From: Carlos Alberto Enciso <carlos.alberto.enciso at gmail.com>
Date: Tue, 24 Oct 2023 13:35:09 +0100
Subject: [PATCH 2/3] [Clang][DebugInfo] Clang generates an extra spurious
 unnamed 'dbg.declare'.

Do not emit call to llvm.dbg.declare when the variable declaration
is a DecompositionDecl as its instance class is always unnamed.

The emitted debug declare looks like:

  call void @llvm.dbg.declare(metadata ..., metadata !xx, metadata ...)
  !xx = !DILocalVariable(scope: !..., file: !..., line: ..., type: !...)

- Remove the added test case.
- Added the '--implicit-check-not' option
- Added checks for variables names.
---
 .../debug-info-structured-binding-field.cpp   | 20 -------------------
 .../debug-info-structured-binding.cpp         | 16 ++++++++++-----
 2 files changed, 11 insertions(+), 25 deletions(-)
 delete mode 100644 clang/test/CodeGenCXX/debug-info-structured-binding-field.cpp

diff --git a/clang/test/CodeGenCXX/debug-info-structured-binding-field.cpp b/clang/test/CodeGenCXX/debug-info-structured-binding-field.cpp
deleted file mode 100644
index 928d22776d21093..000000000000000
--- a/clang/test/CodeGenCXX/debug-info-structured-binding-field.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s
-
-struct Tuple {
-  int Fld_1;
-  int Fld_2;
-};
-__attribute__((optnone)) Tuple get() { return {10, 20}; }
-
-// CHECK-LABEL: define dso_local noundef i32 @main
-// CHECK:      %retval = alloca i32, align 4
-// CHECK-NEXT: [[T0:%.*]] = alloca %struct.Tuple, align 4
-// CHECK:      call void @llvm.dbg.declare(metadata ptr [[T0]], metadata {{.*}}, metadata !DIExpression())
-// CHECK:      call void @llvm.dbg.declare(metadata ptr [[T0]], metadata {{.*}}, metadata !DIExpression(DW_OP_plus_uconst, {{[0-9]+}}))
-// CHECK-NOT:  call void @llvm.dbg.declare(metadata ptr [[T0]], metadata {{.*}}, metadata !DIExpression())
-//
-int main() {
-  auto [Var_1, Var_2] = get();
-
-  return Var_1 + Var_2;
-}
diff --git a/clang/test/CodeGenCXX/debug-info-structured-binding.cpp b/clang/test/CodeGenCXX/debug-info-structured-binding.cpp
index 163c152efa19d0b..2210e278b89c2bd 100644
--- a/clang/test/CodeGenCXX/debug-info-structured-binding.cpp
+++ b/clang/test/CodeGenCXX/debug-info-structured-binding.cpp
@@ -1,9 +1,15 @@
-// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone -triple %itanium_abi_triple %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone -triple %itanium_abi_triple %s -o - | FileCheck %s --implicit-check-not="call void @llvm.dbg.declare"
+
+// CHECK: call void @llvm.dbg.declare(metadata ptr %{{[a-z]+}}, metadata !{{[0-9]+}}, metadata !DIExpression())
+// CHECK: call void @llvm.dbg.declare(metadata ptr %{{[0-9]+}}, metadata ![[VAR_1:[0-9]+]], metadata !DIExpression())
+// CHECK: call void @llvm.dbg.declare(metadata ptr %{{[0-9]+}}, metadata ![[VAR_2:[0-9]+]], metadata !DIExpression(DW_OP_plus_uconst, {{[0-9]+}}))
+// CHECK: call void @llvm.dbg.declare(metadata ptr %{{[0-9]+}}, metadata ![[VAR_3:[0-9]+]], metadata !DIExpression(DW_OP_deref))
+// CHECK: call void @llvm.dbg.declare(metadata ptr %{{[0-9]+}}, metadata ![[VAR_4:[0-9]+]], metadata !DIExpression(DW_OP_deref, DW_OP_plus_uconst, {{[0-9]+}}))
+// CHECK: ![[VAR_1]] = !DILocalVariable(name: "x1"
+// CHECK: ![[VAR_2]] = !DILocalVariable(name: "y1"
+// CHECK: ![[VAR_3]] = !DILocalVariable(name: "x2"
+// CHECK: ![[VAR_4]] = !DILocalVariable(name: "y2"
 
-// CHECK: call void @llvm.dbg.declare(metadata ptr %{{[0-9]+}}, metadata !{{[0-9]+}}, metadata !DIExpression())
-// CHECK: call void @llvm.dbg.declare(metadata ptr %{{[0-9]+}}, metadata !{{[0-9]+}}, metadata !DIExpression(DW_OP_plus_uconst, {{[0-9]+}}))
-// CHECK: call void @llvm.dbg.declare(metadata ptr %{{[0-9]+}}, metadata !{{[0-9]+}}, metadata !DIExpression(DW_OP_deref))
-// CHECK: call void @llvm.dbg.declare(metadata ptr %{{[0-9]+}}, metadata !{{[0-9]+}}, metadata !DIExpression(DW_OP_deref, DW_OP_plus_uconst, {{[0-9]+}}))
 struct A {
   int x;
   int y;

>From d9fe4ff1874b5dd0230b5fe1d14d469ad38f97bb Mon Sep 17 00:00:00 2001
From: Carlos Alberto Enciso <carlos.alberto.enciso at gmail.com>
Date: Wed, 25 Oct 2023 09:28:23 +0100
Subject: [PATCH 3/3] [Clang][DebugInfo] Clang generates an extra spurious
 unnamed 'dbg.declare'.

Do not emit call to llvm.dbg.declare when the variable declaration
is a DecompositionDecl as its instance class is always unnamed.

The emitted debug declare looks like:
  call void @llvm.dbg.declare(metadata ..., metadata !xx, metadata ...)
  !xx = !DILocalVariable(scope: !..., file: !..., line: ..., type: !...)

- Added check for missing captured 'a' variable.
- Check for the specific values in DW_OP_plus_uconst.
---
 clang/test/CodeGenCXX/debug-info-structured-binding.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/clang/test/CodeGenCXX/debug-info-structured-binding.cpp b/clang/test/CodeGenCXX/debug-info-structured-binding.cpp
index 2210e278b89c2bd..7f3c3a08941abce 100644
--- a/clang/test/CodeGenCXX/debug-info-structured-binding.cpp
+++ b/clang/test/CodeGenCXX/debug-info-structured-binding.cpp
@@ -1,10 +1,11 @@
 // RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone -triple %itanium_abi_triple %s -o - | FileCheck %s --implicit-check-not="call void @llvm.dbg.declare"
 
-// CHECK: call void @llvm.dbg.declare(metadata ptr %{{[a-z]+}}, metadata !{{[0-9]+}}, metadata !DIExpression())
+// CHECK: call void @llvm.dbg.declare(metadata ptr %{{[a-z]+}}, metadata ![[VAR_0:[0-9]+]], metadata !DIExpression())
 // CHECK: call void @llvm.dbg.declare(metadata ptr %{{[0-9]+}}, metadata ![[VAR_1:[0-9]+]], metadata !DIExpression())
-// CHECK: call void @llvm.dbg.declare(metadata ptr %{{[0-9]+}}, metadata ![[VAR_2:[0-9]+]], metadata !DIExpression(DW_OP_plus_uconst, {{[0-9]+}}))
+// CHECK: call void @llvm.dbg.declare(metadata ptr %{{[0-9]+}}, metadata ![[VAR_2:[0-9]+]], metadata !DIExpression(DW_OP_plus_uconst, 4))
 // CHECK: call void @llvm.dbg.declare(metadata ptr %{{[0-9]+}}, metadata ![[VAR_3:[0-9]+]], metadata !DIExpression(DW_OP_deref))
-// CHECK: call void @llvm.dbg.declare(metadata ptr %{{[0-9]+}}, metadata ![[VAR_4:[0-9]+]], metadata !DIExpression(DW_OP_deref, DW_OP_plus_uconst, {{[0-9]+}}))
+// CHECK: call void @llvm.dbg.declare(metadata ptr %{{[0-9]+}}, metadata ![[VAR_4:[0-9]+]], metadata !DIExpression(DW_OP_deref, DW_OP_plus_uconst, 4))
+// CHECK: ![[VAR_0]] = !DILocalVariable(name: "a"
 // CHECK: ![[VAR_1]] = !DILocalVariable(name: "x1"
 // CHECK: ![[VAR_2]] = !DILocalVariable(name: "y1"
 // CHECK: ![[VAR_3]] = !DILocalVariable(name: "x2"



More information about the cfe-commits mailing list