[clang] [llvm] Add DW_ATE_GNU_complex_signed to fix assertion (PR #161695)

Orlando Cazalet-Hyams via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 6 02:25:52 PDT 2025


https://github.com/OCHyams updated https://github.com/llvm/llvm-project/pull/161695

>From 49e7792c32ff1f98d4984184e0838f19ebae953a Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Thu, 2 Oct 2025 17:12:23 +0100
Subject: [PATCH 1/2] Add DW_ATE_GNU_complex_signed to fix assertion

Fixes #140362

Clang's `CGDebugInfo::CreateType(const ComplexType *Ty)` already emits this
ATE encoding (0x80) without giving it an explicit name. I chose the name
because it sounded right rather than because I know that's what GNU uses as
I couldn't find that info (but I can see that the 0x80 encoding is what GCC
emits for this example).
---
 clang/lib/CodeGen/CGDebugInfo.cpp             |  2 +-
 llvm/include/llvm/BinaryFormat/Dwarf.def      |  2 +
 .../CodeGen/AsmPrinter/DebugHandlerBase.cpp   |  1 +
 llvm/test/DebugInfo/dwarf-complex-int.ll      | 59 +++++++++++++++++++
 4 files changed, 63 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/DebugInfo/dwarf-complex-int.ll

diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 12c7d48e20d67..c1e21c6c2e0aa 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1119,7 +1119,7 @@ llvm::DIType *CGDebugInfo::CreateType(const ComplexType *Ty) {
   // Bit size and offset of the type.
   llvm::dwarf::TypeKind Encoding = llvm::dwarf::DW_ATE_complex_float;
   if (Ty->isComplexIntegerType())
-    Encoding = llvm::dwarf::DW_ATE_lo_user;
+    Encoding = llvm::dwarf::DW_ATE_GNU_complex_signed;
 
   uint64_t Size = CGM.getContext().getTypeSize(Ty);
   return DBuilder.createBasicType("complex", Size, Encoding);
diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.def b/llvm/include/llvm/BinaryFormat/Dwarf.def
index 2c9a3c0f6fb04..29199b2659f0e 100644
--- a/llvm/include/llvm/BinaryFormat/Dwarf.def
+++ b/llvm/include/llvm/BinaryFormat/Dwarf.def
@@ -1111,6 +1111,8 @@ HANDLE_DW_ATE(0x12, ASCII, 5, DWARF)
 // HANDLE_DW_ATE(0x80, ALTIUM_fract, 2, ALTIUM) = DW_ATE_low_user
 // HANDLE_DW_ATE(0x81, ALTIUM_accum, 2, ALTIUM)
 
+HANDLE_DW_ATE(0x80, GNU_complex_signed, 4, GNU)
+
 HANDLE_DW_ATE(0x81, HP_complex_float, 2, HP)
 HANDLE_DW_ATE(0x82, HP_float128, 2, HP)
 HANDLE_DW_ATE(0x83, HP_complex_float128, 2, HP)
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
index 0f3ff985974ce..983fd7594157b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
@@ -236,6 +236,7 @@ bool DebugHandlerBase::isUnsignedDIType(const DIType *Ty) {
           Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF ||
           Encoding == dwarf::DW_ATE_boolean ||
           Encoding == dwarf::DW_ATE_complex_float ||
+          Encoding == dwarf::DW_ATE_GNU_complex_signed ||
           Encoding == dwarf::DW_ATE_signed_fixed ||
           Encoding == dwarf::DW_ATE_unsigned_fixed ||
           (Ty->getTag() == dwarf::DW_TAG_unspecified_type &&
diff --git a/llvm/test/DebugInfo/dwarf-complex-int.ll b/llvm/test/DebugInfo/dwarf-complex-int.ll
new file mode 100644
index 0000000000000..ad8a1fa78f083
--- /dev/null
+++ b/llvm/test/DebugInfo/dwarf-complex-int.ll
@@ -0,0 +1,59 @@
+; REQUIRES: object-emission
+; RUN: %llc_dwarf %s -filetype=obj -o - | llvm-dwarfdump - | FileCheck %s
+
+;; https://github.com/llvm/llvm-project/issues/140362
+;; Don't assert when emitting a complex integer type in DWARF.
+
+;; C source:
+;; int g;
+;;
+;; void foo(_Complex short c) { __builtin_memmove(&g, (char *)&c, 2); }
+;;
+;; void bar() { foo(0); }
+
+; CHECK: DW_AT_type ([[complex:0x[0-9a-f]+]] "complex")
+
+; CHECK: [[complex]]: DW_TAG_base_type
+; CHECK-NEXT: DW_AT_name        ("complex")
+; CHECK-NEXT: DW_AT_encoding    (DW_ATE_GNU_complex_signed)
+; CHECK-NEXT: DW_AT_byte_size   (0x04)
+
+ at g = dso_local local_unnamed_addr global i32 0, align 4, !dbg !0
+
+define dso_local void @bar() local_unnamed_addr !dbg !18 {
+entry:
+    #dbg_value(i32 0, !21, !DIExpression(), !27)
+  store i16 0, ptr @g, align 4, !dbg !29
+  ret void, !dbg !30
+}
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!10, !11}
+!llvm.ident = !{!17}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "g", scope: !2, file: !8, line: 1, type: !9, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "clang version 22.0.0git", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !4, globals: !7, splitDebugInlining: false, nameTableKind: None)
+!3 = !DIFile(filename: "/app/example.cpp", directory: "/app")
+!4 = !{!5}
+!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64)
+!6 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
+!7 = !{!0}
+!8 = !DIFile(filename: "example.cpp", directory: "/app")
+!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!10 = !{i32 7, !"Dwarf Version", i32 5}
+!11 = !{i32 2, !"Debug Info Version", i32 3}
+!17 = !{!"clang version 22.0.0git"}
+!18 = distinct !DISubprogram(name: "bar", linkageName: "bar()", scope: !8, file: !8, line: 5, type: !19, scopeLine: 5, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, keyInstructions: true)
+!19 = !DISubroutineType(types: !20)
+!20 = !{null}
+!21 = !DILocalVariable(name: "c", arg: 1, scope: !22, file: !8, line: 3, type: !25)
+!22 = distinct !DISubprogram(name: "foo", linkageName: "_ZL3fooCs", scope: !8, file: !8, line: 3, type: !23, scopeLine: 3, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !26, keyInstructions: true)
+!23 = !DISubroutineType(types: !24)
+!24 = !{null, !25}
+!25 = !DIBasicType(name: "complex", size: 32, encoding: 128)
+!26 = !{!21}
+!27 = !DILocation(line: 0, scope: !22, inlinedAt: !28)
+!28 = distinct !DILocation(line: 5, column: 14, scope: !18)
+!29 = !DILocation(line: 3, column: 37, scope: !22, inlinedAt: !28, atomGroup: 1, atomRank: 1)
+!30 = !DILocation(line: 5, column: 22, scope: !18, atomGroup: 1, atomRank: 1)

>From c9b6864d50655d4eb2bf9cc12ed7387f300d1394 Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Mon, 6 Oct 2025 10:25:22 +0100
Subject: [PATCH 2/2] don't name the encoding & don't assert in range lo_user -
 hi_user)

---
 clang/lib/CodeGen/CGDebugInfo.cpp                | 2 +-
 llvm/include/llvm/BinaryFormat/Dwarf.def         | 2 --
 llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp | 4 +++-
 llvm/test/DebugInfo/dwarf-complex-int.ll         | 2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index c1e21c6c2e0aa..12c7d48e20d67 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1119,7 +1119,7 @@ llvm::DIType *CGDebugInfo::CreateType(const ComplexType *Ty) {
   // Bit size and offset of the type.
   llvm::dwarf::TypeKind Encoding = llvm::dwarf::DW_ATE_complex_float;
   if (Ty->isComplexIntegerType())
-    Encoding = llvm::dwarf::DW_ATE_GNU_complex_signed;
+    Encoding = llvm::dwarf::DW_ATE_lo_user;
 
   uint64_t Size = CGM.getContext().getTypeSize(Ty);
   return DBuilder.createBasicType("complex", Size, Encoding);
diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.def b/llvm/include/llvm/BinaryFormat/Dwarf.def
index 29199b2659f0e..2c9a3c0f6fb04 100644
--- a/llvm/include/llvm/BinaryFormat/Dwarf.def
+++ b/llvm/include/llvm/BinaryFormat/Dwarf.def
@@ -1111,8 +1111,6 @@ HANDLE_DW_ATE(0x12, ASCII, 5, DWARF)
 // HANDLE_DW_ATE(0x80, ALTIUM_fract, 2, ALTIUM) = DW_ATE_low_user
 // HANDLE_DW_ATE(0x81, ALTIUM_accum, 2, ALTIUM)
 
-HANDLE_DW_ATE(0x80, GNU_complex_signed, 4, GNU)
-
 HANDLE_DW_ATE(0x81, HP_complex_float, 2, HP)
 HANDLE_DW_ATE(0x82, HP_float128, 2, HP)
 HANDLE_DW_ATE(0x83, HP_complex_float128, 2, HP)
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
index 983fd7594157b..85035eda79ab0 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/CodeGen/DebugHandlerBase.h"
+#include "llvm/BinaryFormat/Dwarf.h"
 #include "llvm/CodeGen/AsmPrinter.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstr.h"
@@ -236,9 +237,10 @@ bool DebugHandlerBase::isUnsignedDIType(const DIType *Ty) {
           Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF ||
           Encoding == dwarf::DW_ATE_boolean ||
           Encoding == dwarf::DW_ATE_complex_float ||
-          Encoding == dwarf::DW_ATE_GNU_complex_signed ||
           Encoding == dwarf::DW_ATE_signed_fixed ||
           Encoding == dwarf::DW_ATE_unsigned_fixed ||
+          (Encoding >= dwarf::DW_ATE_lo_user &&
+           Encoding <= dwarf::DW_ATE_hi_user) ||
           (Ty->getTag() == dwarf::DW_TAG_unspecified_type &&
            Ty->getName() == "decltype(nullptr)")) &&
          "Unsupported encoding");
diff --git a/llvm/test/DebugInfo/dwarf-complex-int.ll b/llvm/test/DebugInfo/dwarf-complex-int.ll
index ad8a1fa78f083..effd0ece2c445 100644
--- a/llvm/test/DebugInfo/dwarf-complex-int.ll
+++ b/llvm/test/DebugInfo/dwarf-complex-int.ll
@@ -15,7 +15,7 @@
 
 ; CHECK: [[complex]]: DW_TAG_base_type
 ; CHECK-NEXT: DW_AT_name        ("complex")
-; CHECK-NEXT: DW_AT_encoding    (DW_ATE_GNU_complex_signed)
+; CHECK-NEXT: DW_AT_encoding    (0x80)
 ; CHECK-NEXT: DW_AT_byte_size   (0x04)
 
 @g = dso_local local_unnamed_addr global i32 0, align 4, !dbg !0



More information about the llvm-commits mailing list