[flang-commits] [flang] 25e94da - [flang][debug] Fix DIStringType size for arrays of assumed-length chars. (#201649)

via flang-commits flang-commits at lists.llvm.org
Fri Jun 5 03:05:25 PDT 2026


Author: Abid Qadeer
Date: 2026-06-05T11:05:19+01:00
New Revision: 25e94da798b1ddc24c8680e8fe0b6f4099e7e876

URL: https://github.com/llvm/llvm-project/commit/25e94da798b1ddc24c8680e8fe0b6f4099e7e876
DIFF: https://github.com/llvm/llvm-project/commit/25e94da798b1ddc24c8680e8fe0b6f4099e7e876.diff

LOG: [flang][debug] Fix DIStringType size for arrays of assumed-length chars. (#201649)

When generating DWARF for an assumed-shape array whose element type is
an assumed-length character, `convertBoxedSequenceType` called
`convertType` for the element, which in turn called
`convertCharacterType` with `hasDescriptor`=false. With no descriptor
and a non-constant length, none of the branches that set `sizeInBits` or
produce a length expression were taken, so the resulting
`DIStringTypeAttr` had `sizeInBits` equal to =0 and no
`stringLengthExp`, leaving GDB unable to determine the string length or
display the array elements.

Fix this by detecting a non-constant-length character element in
`convertBoxedSequenceType` and calling `convertCharacterType` directly
with `hasDescriptor=true`. This generates the correct `stringLengthExp`
that reads the element byte-size from the descriptor. A
`genStringLocation` parameter (default true) is also added to suppress
the string location expression for the element type, since the data
location of array elements is already provided by the enclosing array.

Fixes https://github.com/llvm/llvm-project/issues/113895

Added: 
    flang/test/Transforms/debug-char-type-2.fir

Modified: 
    flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
    flang/lib/Optimizer/Transforms/DebugTypeGenerator.h

Removed: 
    


################################################################################
diff  --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
index f6e18c5b27391..5fc11fefb207d 100644
--- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
@@ -142,8 +142,20 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertBoxedSequenceType(
       mlir::LLVM::DIExpressionAttr::get(context, ops);
   ops.clear();
 
-  mlir::LLVM::DITypeAttr elemTy =
-      convertType(seqTy.getEleTy(), fileAttr, scope, declOp);
+  // For a descriptor-based array of characters with non-constant (assumed or
+  // deferred) length, the length of each element is stored in the descriptor.
+  // We generate a string length expression that reads it from there. The data
+  // location of the elements is provided by the enclosing array so we do not
+  // generate a string location expression for the element type itself.
+  mlir::LLVM::DITypeAttr elemTy;
+  if (auto charTy =
+          mlir::dyn_cast_if_present<fir::CharacterType>(seqTy.getEleTy());
+      charTy && !charTy.hasConstantLen())
+    elemTy = convertCharacterType(charTy, fileAttr, scope, declOp,
+                                  /*hasDescriptor=*/true,
+                                  /*genStringLocation=*/false);
+  else
+    elemTy = convertType(seqTy.getEleTy(), fileAttr, scope, declOp);
 
   // Assumed-rank arrays
   if (seqTy.hasUnknownShape()) {
@@ -612,7 +624,7 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertVectorType(
 mlir::LLVM::DITypeAttr DebugTypeGenerator::convertCharacterType(
     fir::CharacterType charTy, mlir::LLVM::DIFileAttr fileAttr,
     mlir::LLVM::DIScopeAttr scope, fir::cg::XDeclareOp declOp,
-    bool hasDescriptor) {
+    bool hasDescriptor, bool genStringLocation) {
   mlir::MLIRContext *context = module.getContext();
 
   // DWARF 5 says the following about the character encoding in 5.1.1.2.
@@ -638,9 +650,14 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertCharacterType(
     lenExpr = mlir::LLVM::DIExpressionAttr::get(context, ops);
     ops.clear();
 
-    addOp(llvm::dwarf::DW_OP_push_object_address, {});
-    addOp(llvm::dwarf::DW_OP_deref, {});
-    locExpr = mlir::LLVM::DIExpressionAttr::get(context, ops);
+    // When the character is an element of a descriptor-based array, the data
+    // location is provided by the enclosing array type and a string location
+    // expression must not be generated for the element itself.
+    if (genStringLocation) {
+      addOp(llvm::dwarf::DW_OP_push_object_address, {});
+      addOp(llvm::dwarf::DW_OP_deref, {});
+      locExpr = mlir::LLVM::DIExpressionAttr::get(context, ops);
+    }
   } else if (charTy.hasConstantLen()) {
     sizeInBits =
         charTy.getLen() * kindMapping.getCharacterBitsize(charTy.getFKind());

diff  --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
index 854e4397ca32b..2605c114b9b8c 100644
--- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
@@ -135,7 +135,8 @@ class DebugTypeGenerator {
                                               mlir::LLVM::DIFileAttr fileAttr,
                                               mlir::LLVM::DIScopeAttr scope,
                                               fir::cg::XDeclareOp declOp,
-                                              bool hasDescriptor);
+                                              bool hasDescriptor,
+                                              bool genStringLocation = true);
 
   mlir::LLVM::DITypeAttr convertPointerLikeType(mlir::Type elTy,
                                                 mlir::LLVM::DIFileAttr fileAttr,

diff  --git a/flang/test/Transforms/debug-char-type-2.fir b/flang/test/Transforms/debug-char-type-2.fir
new file mode 100644
index 0000000000000..7be81224d8a04
--- /dev/null
+++ b/flang/test/Transforms/debug-char-type-2.fir
@@ -0,0 +1,19 @@
+// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s
+
+// Test that an assumed-shape array of assumed-length characters gets a
+// string element type whose length is read from the descriptor.
+
+module {
+  func.func @_QFPshow(%arg0: !fir.box<!fir.array<?x!fir.char<1,?>>> {fir.bindc_name = "akeys"}) {
+    %0 = fir.undefined !fir.dscope
+    %1 = fircg.ext_declare %arg0 dummy_scope %0 {uniq_name = "_QFFshowEakeys"} : (!fir.box<!fir.array<?x!fir.char<1,?>>>, !fir.dscope) -> !fir.box<!fir.array<?x!fir.char<1,?>>> loc(#loc1)
+    return
+  } loc(#loc2)
+}
+#loc1 = loc("string.f90":16:1)
+#loc2 = loc("string.f90":15:1)
+
+// CHECK: #[[STR:.*]] = #llvm.di_string_type<tag = DW_TAG_string_type, name = "", stringLengthExp = <[DW_OP_push_object_address, DW_OP_plus_uconst(8)]>, encoding = DW_ATE_ASCII>
+// CHECK: #[[ARR:.*]] = #llvm.di_composite_type<tag = DW_TAG_array_type, {{.*}}baseType = #[[STR]]
+// CHECK-SAME: dataLocation = <[DW_OP_push_object_address, DW_OP_deref]>
+// CHECK: #llvm.di_local_variable<{{.*}}name = "akeys"{{.*}}type = #[[ARR]]>


        


More information about the flang-commits mailing list