[flang-commits] [flang] 64c39dd - [flang][debug] Only import debug info for specified renamed variables (#194926)

via flang-commits flang-commits at lists.llvm.org
Mon May 18 05:37:26 PDT 2026


Author: Tim
Date: 2026-05-18T13:37:21+01:00
New Revision: 64c39dd22f6aa9a72fa2c9e68d6ce6b2e3743572

URL: https://github.com/llvm/llvm-project/commit/64c39dd22f6aa9a72fa2c9e68d6ce6b2e3743572
DIFF: https://github.com/llvm/llvm-project/commit/64c39dd22f6aa9a72fa2c9e68d6ce6b2e3743572.diff

LOG: [flang][debug] Only import debug info for specified renamed variables (#194926)

Given the following:

USE mod, ONLY : alias => var

Currently, flang will create a DW_TAG_imported_module tag for mod when
it should only be creating a list of DW_TAG_imported_declaration tags
for each imported variable. This causes erroneous variables from mod to
be visible in the debugger with undefined information.

The correct logic to do this was previously implemented at line 837 in
flang/lib/Optimizer/Transforms/AddDebugInfo.cpp under the comment "//
Process renames within ONLY clause". But this code block would never be
invoked as the function handleOnlyClause would never be called as only
one of renames or ONLY clauses could be present at once, not both. This
commit fixes the logic and allows the proper code block to be called.

Fixes #180836

Added: 
    

Modified: 
    flang/include/flang/Optimizer/Dialect/FIROps.td
    flang/include/flang/Semantics/scope.h
    flang/lib/Lower/Bridge.cpp
    flang/lib/Lower/PFTBuilder.cpp
    flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
    flang/test/Integration/debug-use-stmt.f90
    flang/test/Lower/debug-use-stmt.f90

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td
index 453379b010075..17e0d485b90b1 100644
--- a/flang/include/flang/Optimizer/Dialect/FIROps.td
+++ b/flang/include/flang/Optimizer/Dialect/FIROps.td
@@ -3314,12 +3314,14 @@ def fir_UseStmtOp
   }];
 
   let arguments = (ins StrAttr:$module_name,
-      OptionalAttr<ArrayAttr>:$only_symbols, OptionalAttr<ArrayAttr>:$renames);
+      OptionalAttr<ArrayAttr>:$only_symbols, OptionalAttr<ArrayAttr>:$renames,
+      DefaultValuedAttr<BoolAttr, "false">:$hasOnlyWithRenames);
 
   let assemblyFormat = [{
     $module_name
     (`only_symbols` `[` $only_symbols^ `]`)?
     (`renames` `[` $renames^ `]`)?
+    (`hasOnlyWithRenames` $hasOnlyWithRenames^)?
     attr-dict
   }];
 
@@ -3331,7 +3333,10 @@ def fir_UseStmtOp
     bool hasRenames() { return getRenames().has_value(); }
 
     /// Returns true if this imports the entire module (no ONLY clause)
-    bool importsAll() { return !hasOnlyClause(); }
+    bool importsAll() { return !(hasOnlyClause() || getHasOnlyWithRenames()); }
+
+    /// Returns true if this USE statement has both ONLY clause and renames
+    bool hasOnlyWithRenames() { return getHasOnlyWithRenames(); }
   }];
 }
 

diff  --git a/flang/include/flang/Semantics/scope.h b/flang/include/flang/Semantics/scope.h
index 16553fe692e79..7cab6e2122319 100644
--- a/flang/include/flang/Semantics/scope.h
+++ b/flang/include/flang/Semantics/scope.h
@@ -60,6 +60,7 @@ struct PreservedUseStmt {
   std::string moduleName;
   std::vector<std::string> onlyNames; // For USE ONLY
   std::vector<std::string> renames; // local_name (resolved via GetUltimate)
+  bool hasOnlyWithRenames{false}; // true if there are renames in an ONLY clause
 
   PreservedUseStmt(std::string modName) : moduleName(std::move(modName)) {}
 };

diff  --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 01482c1cb90b5..9c5cf84b1d77a 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -283,9 +283,11 @@ static void emitUseStmtOp(Fortran::lower::AbstractConverter &converter,
   mlir::ArrayAttr renamesAttr =
       renameAttrs.empty() ? mlir::ArrayAttr()
                           : mlir::ArrayAttr::get(context, renameAttrs);
+  mlir::BoolAttr hasOnlyWithRenamesAttr =
+      mlir::BoolAttr::get(context, stmt.hasOnlyWithRenames);
 
   fir::UseStmtOp::create(builder, loc, moduleNameAttr, onlySymbolsAttr,
-                         renamesAttr);
+                         renamesAttr, hasOnlyWithRenamesAttr);
 }
 
 /// Emit fir.module_debug_imports for USE statements in a module.

diff  --git a/flang/lib/Lower/PFTBuilder.cpp b/flang/lib/Lower/PFTBuilder.cpp
index afabb6b29f4f1..a7cf64ccb583b 100644
--- a/flang/lib/Lower/PFTBuilder.cpp
+++ b/flang/lib/Lower/PFTBuilder.cpp
@@ -253,6 +253,7 @@ class PFTBuilder {
                             std::string localName{
                                 std::get<0>(names.t).source.ToString()};
                             stmt.renames.push_back(localName);
+                            stmt.hasOnlyWithRenames = true;
                           },
                           [&](const parser::Rename::Operators &) {
                             // Operator renames - not commonly needed for debug

diff  --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index 65c8508de9c9f..e0b570a908521 100644
--- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
+++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
@@ -908,7 +908,7 @@ void AddDebugInfoPass::expandUseStmtForDebug(
                             /*decl=*/true);
 
   llvm::DenseSet<mlir::LLVM::DIImportedEntityAttr> importedModules;
-  if (useOp.hasOnlyClause())
+  if (useOp.hasOnlyClause() || useOp.getHasOnlyWithRenames())
     handleOnlyClause(useOp, spAttr, fileAttr, symbolTable, importedModules);
   else if (useOp.hasRenames())
     handleRenamesWithoutOnly(useOp, spAttr, modAttr, fileAttr, symbolTable,

diff  --git a/flang/test/Integration/debug-use-stmt.f90 b/flang/test/Integration/debug-use-stmt.f90
index db20dd94e85d1..50a70da3941f8 100644
--- a/flang/test/Integration/debug-use-stmt.f90
+++ b/flang/test/Integration/debug-use-stmt.f90
@@ -26,6 +26,8 @@ program test_use
 
 ! CHECK-DAG: [[SP:![0-9]+]] = distinct !DISubprogram(name: "TEST_USE", linkageName: "_QQmain"{{.*}}retainedNodes:
 
+! Check that the full testmod module is not imported
+! CHECK-NOT: !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[SP]], entity: [[TESTMOD]]
 ! Check testmod imports: var_b directly (no rename), var_d as rename of var_c
 ! CHECK-DAG: !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[SP]], entity: [[VAR_B]],{{.*}}file:{{.*}}line:
 ! CHECK-DAG: !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "var_d", scope: [[SP]], entity: [[VAR_C]],{{.*}}file:{{.*}}line:

diff  --git a/flang/test/Lower/debug-use-stmt.f90 b/flang/test/Lower/debug-use-stmt.f90
index 293b38c78e17a..9701d938b5f0b 100644
--- a/flang/test/Lower/debug-use-stmt.f90
+++ b/flang/test/Lower/debug-use-stmt.f90
@@ -73,8 +73,8 @@ subroutine test_only_rename()
 ! NO_DEBUG-NOT: fir.use_stmt
 
 ! WITH_DEBUG-LABEL: func.func @_QPtest_only_rename()
-! WITH_DEBUG-DAG: fir.use_stmt "mod1" only_symbols{{\[}}[@_QMmod1Ec]] renames{{\[}}[#fir.use_rename<"local_b", @_QMmod1Eb>, #fir.use_rename<"local_a", @_QMmod1Ea>]]
-! WITH_DEBUG-DAG: fir.use_stmt "mod2" renames{{\[}}[#fir.use_rename<"local_x", @_QMmod2Ex>, #fir.use_rename<"local_y", @_QMmod2Ey>]]
+! WITH_DEBUG-DAG: fir.use_stmt "mod1" only_symbols{{\[}}[@_QMmod1Ec]] renames{{\[}}[#fir.use_rename<"local_b", @_QMmod1Eb>, #fir.use_rename<"local_a", @_QMmod1Ea>]] hasOnlyWithRenames true
+! WITH_DEBUG-DAG: fir.use_stmt "mod2" renames{{\[}}[#fir.use_rename<"local_x", @_QMmod2Ex>, #fir.use_rename<"local_y", @_QMmod2Ey>]] hasOnlyWithRenames true
 
 ! NO_DEBUG-LABEL: func.func @_QPtest_only_rename()
 ! NO_DEBUG-NOT: fir.use_stmt


        


More information about the flang-commits mailing list