From 49e7792c32ff1f98d4984184e0838f19ebae953a Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams Date: Thu, 2 Oct 2025 17:12:23 +0100 Subject: [PATCH 1/3] 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) + +@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 Date: Mon, 6 Oct 2025 10:25:22 +0100 Subject: [PATCH 2/3] 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 From 191fe1cb594d1a2b8e1c0f5aae4b3b96b0fb039d Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams Date: Mon, 6 Oct 2025 10:33:54 +0100 Subject: [PATCH 3/3] remove unecessarily added include2 --- llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp index 85035eda79ab0..9fcf1510e83d8 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// #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"