[flang-commits] [flang] [flang] Fix extra "./" prefix in source file paths (PR #186212)

Caroline Newcombe via flang-commits flang-commits at lists.llvm.org
Sun Mar 15 18:45:27 PDT 2026


https://github.com/cenewcombe updated https://github.com/llvm/llvm-project/pull/186212

>From dce42ef1cdc3fb0854687f5ddaa286e1bc7ba0a6 Mon Sep 17 00:00:00 2001
From: Caroline Newcombe <caroline.newcombe at hpe.com>
Date: Thu, 12 Mar 2026 13:28:31 -0500
Subject: [PATCH 1/2] [flang] Fix extra "./" prefix in source file paths

When a relative path starting with "./" (e.g., "./test.F90") was passed
to LocateSourceFile, llvm::sys::path::append(".", "./test.F90") produced
"././test.F90". This caused the __FILE__ macro to expand incorrectly:

  $ flang-new ./test.F90   # __FILE__ = "././test.F90" (wrong)

Fix this by:
1. In LocateSourceFile, checking whether the file exists at the original
   path before searching, preserving the user's format. Then normalizing
   the name by stripping a leading "./" before appending to search paths.
2. In LocateSourceFileAll, applying the same "./" normalization before
   the search loop to prevent the doubled prefix.

The test expectation in getsymbols02.f90 is updated because the old
CHECK patterns matched the buggy "././" output.
---
 flang/lib/Parser/source.cpp           | 22 ++++++++++++++++++++--
 flang/test/Semantics/getsymbols02.f90 |  4 ++--
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/flang/lib/Parser/source.cpp b/flang/lib/Parser/source.cpp
index 6313373675e5b..17779f20fdcfa 100644
--- a/flang/lib/Parser/source.cpp
+++ b/flang/lib/Parser/source.cpp
@@ -63,9 +63,21 @@ std::optional<std::string> LocateSourceFile(
   if (name == "-" || llvm::sys::path::is_absolute(name)) {
     return name;
   }
+  // Check if file exists at original path to preserve user's format.
+  bool isDir{false};
+  const auto er = llvm::sys::fs::is_directory(name, isDir);
+  if (!er && !isDir) {
+    return name;
+  }
+  // Normalize: strip leading "./" to avoid "././file" with "." search paths.
+  llvm::StringRef nameRef(name);
+  if (nameRef.starts_with("./")) {
+    nameRef = nameRef.substr(2);
+  }
+  std::string normalizedName = nameRef.str();
   for (const std::string &dir : searchPath) {
     llvm::SmallString<128> path{dir};
-    llvm::sys::path::append(path, name);
+    llvm::sys::path::append(path, normalizedName);
     bool isDir{false};
     auto er = llvm::sys::fs::is_directory(path, isDir);
     if (!er && !isDir) {
@@ -81,9 +93,15 @@ std::vector<std::string> LocateSourceFileAll(
     return {name};
   }
   std::vector<std::string> result;
+  // Normalize: strip leading "./" to avoid "././file" with "." search paths.
+  llvm::StringRef nameRef(name);
+  if (nameRef.starts_with("./")) {
+    nameRef = nameRef.substr(2);
+  }
+  std::string normalizedName = nameRef.str();
   for (const std::string &dir : searchPath) {
     llvm::SmallString<128> path{dir};
-    llvm::sys::path::append(path, name);
+    llvm::sys::path::append(path, normalizedName);
     bool isDir{false};
     auto er = llvm::sys::fs::is_directory(path, isDir);
     if (!er && !isDir) {
diff --git a/flang/test/Semantics/getsymbols02.f90 b/flang/test/Semantics/getsymbols02.f90
index 2605a593e814d..25f63193387eb 100644
--- a/flang/test/Semantics/getsymbols02.f90
+++ b/flang/test/Semantics/getsymbols02.f90
@@ -10,5 +10,5 @@ PROGRAM helloworld
 ! RUN: %flang_fc1 -fsyntax-only %S/Inputs/getsymbols02-a.f90
 ! RUN: %flang_fc1 -fsyntax-only %S/Inputs/getsymbols02-b.f90
 ! RUN: %flang_fc1 -fget-symbols-sources %s 2>&1 | FileCheck %s
-! CHECK: callget5: .{{[/\\]}}mm2b.mod,
-! CHECK: get5: .{{[/\\]}}.{{[/\\]}}mm2a.mod,
+! CHECK: callget5: mm2b.mod,
+! CHECK: get5: .{{[/\\]}}mm2a.mod,

>From dee908908852d8c043f70b330f8c50293a0dfe22 Mon Sep 17 00:00:00 2001
From: Caroline Newcombe <caroline.newcombe at hpe.com>
Date: Sun, 15 Mar 2026 20:44:17 -0500
Subject: [PATCH 2/2] [flang] Don't append "./" to source file paths in current
 working directory

---
 flang/lib/Parser/source.cpp           | 40 ++++++++++++---------------
 flang/test/Semantics/getsymbols02.f90 |  2 +-
 2 files changed, 19 insertions(+), 23 deletions(-)

diff --git a/flang/lib/Parser/source.cpp b/flang/lib/Parser/source.cpp
index 17779f20fdcfa..f144d8ff426ba 100644
--- a/flang/lib/Parser/source.cpp
+++ b/flang/lib/Parser/source.cpp
@@ -63,21 +63,16 @@ std::optional<std::string> LocateSourceFile(
   if (name == "-" || llvm::sys::path::is_absolute(name)) {
     return name;
   }
-  // Check if file exists at original path to preserve user's format.
-  bool isDir{false};
-  const auto er = llvm::sys::fs::is_directory(name, isDir);
-  if (!er && !isDir) {
-    return name;
-  }
-  // Normalize: strip leading "./" to avoid "././file" with "." search paths.
-  llvm::StringRef nameRef(name);
-  if (nameRef.starts_with("./")) {
-    nameRef = nameRef.substr(2);
-  }
-  std::string normalizedName = nameRef.str();
   for (const std::string &dir : searchPath) {
-    llvm::SmallString<128> path{dir};
-    llvm::sys::path::append(path, normalizedName);
+    llvm::SmallString<128> path;
+    // If the file is found in the current directory, don't append the
+    // directory path. This preserves the user's format.
+    if (dir == ".") {
+      path = name;
+    } else {
+      path = dir;
+      llvm::sys::path::append(path, name);
+    }
     bool isDir{false};
     auto er = llvm::sys::fs::is_directory(path, isDir);
     if (!er && !isDir) {
@@ -93,15 +88,16 @@ std::vector<std::string> LocateSourceFileAll(
     return {name};
   }
   std::vector<std::string> result;
-  // Normalize: strip leading "./" to avoid "././file" with "." search paths.
-  llvm::StringRef nameRef(name);
-  if (nameRef.starts_with("./")) {
-    nameRef = nameRef.substr(2);
-  }
-  std::string normalizedName = nameRef.str();
   for (const std::string &dir : searchPath) {
-    llvm::SmallString<128> path{dir};
-    llvm::sys::path::append(path, normalizedName);
+    llvm::SmallString<128> path;
+    // If the file is found in the current directory, don't append the
+    // directory path. This preserves the user's format.
+    if (dir == ".") {
+      path = name;
+    } else {
+      path = dir;
+      llvm::sys::path::append(path, name);
+    }
     bool isDir{false};
     auto er = llvm::sys::fs::is_directory(path, isDir);
     if (!er && !isDir) {
diff --git a/flang/test/Semantics/getsymbols02.f90 b/flang/test/Semantics/getsymbols02.f90
index 25f63193387eb..cb927e6d4c5ed 100644
--- a/flang/test/Semantics/getsymbols02.f90
+++ b/flang/test/Semantics/getsymbols02.f90
@@ -11,4 +11,4 @@ PROGRAM helloworld
 ! RUN: %flang_fc1 -fsyntax-only %S/Inputs/getsymbols02-b.f90
 ! RUN: %flang_fc1 -fget-symbols-sources %s 2>&1 | FileCheck %s
 ! CHECK: callget5: mm2b.mod,
-! CHECK: get5: .{{[/\\]}}mm2a.mod,
+! CHECK: get5: mm2a.mod,



More information about the flang-commits mailing list