[llvm] [Support] Preserve tilde paths when home lookup fails (PR #209479)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 14 06:47:56 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-support

Author: NotPppp1116

<details>
<summary>Changes</summary>

## What

- preserve a normalized `~` path when the home-directory lookup fails
- treat an empty `HOME` value as unavailable and fall back to the password database on Unix
- add coverage for the empty-`HOME` fallback

## Why

`path::native` unconditionally replaced a tilde-prefixed path with the home lookup output. If that lookup failed, `~/file` became `/file`. An empty `HOME` was also accepted as a successful lookup, producing the same incorrect expansion even when the password database contained a valid home directory.

## Impact

Failed expansion leaves the normalized tilde path intact, while an empty Unix `HOME` now uses the existing password-database fallback.

## Checks

- built `SupportTests`
- `Support.HomeDirectory*`: 3/3 passed


---
Full diff: https://github.com/llvm/llvm-project/pull/209479.diff


3 Files Affected:

- (modified) llvm/lib/Support/Path.cpp (+4-3) 
- (modified) llvm/lib/Support/Unix/Path.inc (+1-1) 
- (modified) llvm/unittests/Support/Path.cpp (+14) 


``````````diff
diff --git a/llvm/lib/Support/Path.cpp b/llvm/lib/Support/Path.cpp
index 65e294020291f..e4b505653b1de 100644
--- a/llvm/lib/Support/Path.cpp
+++ b/llvm/lib/Support/Path.cpp
@@ -573,9 +573,10 @@ void native(SmallVectorImpl<char> &Path, Style style) {
         Ch = preferred_separator(style);
     if (Path[0] == '~' && (Path.size() == 1 || is_separator(Path[1], style))) {
       SmallString<128> PathHome;
-      home_directory(PathHome);
-      PathHome.append(Path.begin() + 1, Path.end());
-      Path = std::move(PathHome);
+      if (home_directory(PathHome)) {
+        PathHome.append(Path.begin() + 1, Path.end());
+        Path = std::move(PathHome);
+      }
     }
   } else {
     llvm::replace(Path, '\\', '/');
diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc
index f5b01357565df..bd897c27344da 100644
--- a/llvm/lib/Support/Unix/Path.inc
+++ b/llvm/lib/Support/Unix/Path.inc
@@ -1493,7 +1493,7 @@ namespace path {
 bool home_directory(SmallVectorImpl<char> &result) {
   std::unique_ptr<char[]> Buf;
   char *RequestedDir = getenv("HOME");
-  if (!RequestedDir) {
+  if (!RequestedDir || !*RequestedDir) {
     long BufSize = sysconf(_SC_GETPW_R_SIZE_MAX);
     if (BufSize <= 0)
       BufSize = 16384;
diff --git a/llvm/unittests/Support/Path.cpp b/llvm/unittests/Support/Path.cpp
index b63ab426bb080..1234345eb7c5b 100644
--- a/llvm/unittests/Support/Path.cpp
+++ b/llvm/unittests/Support/Path.cpp
@@ -513,6 +513,20 @@ TEST(Support, HomeDirectoryWithNoEnv) {
   EXPECT_EQ(PwDir, HomeDir);
 }
 
+TEST(Support, HomeDirectoryWithEmptyEnv) {
+  WithEnv Env("HOME", "");
+
+  // Don't run the test if we have nothing to compare against.
+  struct passwd *pw = getpwuid(getuid());
+  if (!pw || !pw->pw_dir)
+    GTEST_SKIP();
+  std::string PwDir = pw->pw_dir;
+
+  SmallString<128> HomeDir;
+  EXPECT_TRUE(path::home_directory(HomeDir));
+  EXPECT_EQ(PwDir, HomeDir);
+}
+
 TEST(Support, ConfigDirectoryWithEnv) {
   WithEnv Env("XDG_CONFIG_HOME", "/xdg/config");
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/209479


More information about the llvm-commits mailing list