https://github.com/charles-zablit updated 
https://github.com/llvm/llvm-project/pull/209409

>From fa2a80b744944f03b760bb071cb659ebc98fa3b3 Mon Sep 17 00:00:00 2001
From: Charles Zablit <[email protected]>
Date: Tue, 14 Jul 2026 10:18:34 +0100
Subject: [PATCH 1/2] [lldb][Windows] Use extended path prefix for rmtree

---
 lldb/packages/Python/lldbsuite/test/lldbtest.py | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py 
b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index a9c229be1a771..2fc8601f93974 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -846,7 +846,12 @@ def _ignore_enoent(func, path, exc_info):
                     return
                 raise exc_info[1]
 
-            shutil.rmtree(bdir, onerror=_ignore_enoent)
+            # Delete via the \\?\ extended length path prefix so rmtree can
+            # remove build artifacts whose full path exceeds MAX_PATH (260).
+            rmtree_target = bdir
+            if sys.platform == "win32":
+                rmtree_target = "\\\\?\\" + bdir
+            shutil.rmtree(rmtree_target, onerror=_ignore_enoent)
         lldbutil.mkdir_p(bdir)
 
     def getBuildArtifact(self, name="a.out"):

>From 3025dbfe0bedf77d1d2ebef49bf9093b91db4f00 Mon Sep 17 00:00:00 2001
From: Charles Zablit <[email protected]>
Date: Tue, 14 Jul 2026 13:00:28 +0100
Subject: [PATCH 2/2] fixup! [lldb][Windows] Use extended path prefix for
 rmtree

---
 .../Python/lldbsuite/test/lldbtest.py         | 28 ++++---------------
 .../Python/lldbsuite/test/lldbutil.py         | 24 ++++++++++++++++
 .../API/driver/longpath/TestLongPathDriver.py |  3 +-
 .../functionalities/longpath/TestLongPath.py  |  2 +-
 .../longpath/TestDAP_launch_longPath.py       |  3 +-
 lldb/test/Shell/helper/toolchain.py           |  7 -----
 6 files changed, 35 insertions(+), 32 deletions(-)

diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py 
b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index 2fc8601f93974..fbc06af87a246 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -824,13 +824,6 @@ def makeBuildDir(self):
         """Create the test-specific working directory, optionally deleting any
         previous contents."""
         bdir = self.getBuildDir()
-        if sys.platform == "win32" and len(bdir) > 256:
-            import warnings
-
-            warnings.warn(
-                "Test build directory path exceeds 256 characters (Windows "
-                "MAX_PATH limit): {}".format(bdir)
-            )
         if os.path.isdir(bdir) and not self.SHARED_BUILD_TESTCASE:
             # Tolerate files vanishing mid-walk. Clang's implicit module
             # build leaves behind `*.pcm.lock` lockfiles whose lifetime is
@@ -846,25 +839,16 @@ def _ignore_enoent(func, path, exc_info):
                     return
                 raise exc_info[1]
 
-            # Delete via the \\?\ extended length path prefix so rmtree can
-            # remove build artifacts whose full path exceeds MAX_PATH (260).
-            rmtree_target = bdir
-            if sys.platform == "win32":
-                rmtree_target = "\\\\?\\" + bdir
-            shutil.rmtree(rmtree_target, onerror=_ignore_enoent)
+            # Delete via the \\?\ extended-length path form so rmtree can 
remove
+            # build artifacts whose full path exceeds MAX_PATH (260) on 
Windows.
+            shutil.rmtree(
+                lldbutil.get_extended_windows_path(bdir), 
onerror=_ignore_enoent
+            )
         lldbutil.mkdir_p(bdir)
 
     def getBuildArtifact(self, name="a.out"):
         """Return absolute path to an artifact in the test's build 
directory."""
-        artifact_path = os.path.join(self.getBuildDir(), name)
-        if sys.platform == "win32" and len(artifact_path) > 256:
-            import warnings
-
-            warnings.warn(
-                "Test artifact path exceeds 256 characters (Windows "
-                "MAX_PATH limit): {}".format(artifact_path)
-            )
-        return artifact_path
+        return os.path.join(self.getBuildDir(), name)
 
     def getSourcePath(self, name):
         """Return absolute path to a file in the test's source directory."""
diff --git a/lldb/packages/Python/lldbsuite/test/lldbutil.py 
b/lldb/packages/Python/lldbsuite/test/lldbutil.py
index 91f872bce3827..8fd2c18deba79 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbutil.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbutil.py
@@ -59,6 +59,30 @@ def mkdir_p(path):
         raise OSError(errno.ENOTDIR, "%s is not a directory" % path)
 
 
+def get_extended_windows_path(path):
+    r"""Return ``path`` in the Windows extended-length ``\\?\`` form so it can 
be
+    handed to the Win32 API (and therefore to ``os``/``shutil``) even when it 
is
+    longer than MAX_PATH (260 characters). On non-Windows platforms ``path`` is
+    returned unchanged.
+
+    The ``\\?\`` prefix disables all path normalization normally performed by
+    Win32, so the path must be fully qualified, use backslash separators and
+    contain no ``.``/``..`` components. ``os.path.abspath`` guarantees all 
three.
+    """
+    if sys.platform != "win32":
+        return path
+    if path.startswith("\\\\?\\"):
+        return path
+    assert os.path.isabs(path), (
+        "cannot form a \\\\?\\ extended-length path from relative path: %s" % 
path
+    )
+    abs_path = os.path.abspath(path)
+    # UNC shares (\\server\share) use the \\?\UNC\ spelling.
+    if abs_path.startswith("\\\\"):
+        return "\\\\?\\UNC\\" + abs_path[2:]
+    return "\\\\?\\" + abs_path
+
+
 # ============================
 # Dealing with SDK and triples
 # ============================
diff --git a/lldb/test/API/driver/longpath/TestLongPathDriver.py 
b/lldb/test/API/driver/longpath/TestLongPathDriver.py
index 280180391790f..c74229b860367 100644
--- a/lldb/test/API/driver/longpath/TestLongPathDriver.py
+++ b/lldb/test/API/driver/longpath/TestLongPathDriver.py
@@ -10,6 +10,7 @@
 import lldb
 from lldbsuite.test.decorators import *
 from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
 
 MAX_PATH = 260
 
@@ -19,7 +20,7 @@ class DriverLongPathTestCase(TestBase):
     NO_DEBUG_INFO_TESTCASE = True
 
     def _long_path(self, path):
-        return "\\\\?\\" + os.path.abspath(path)
+        return lldbutil.get_extended_windows_path(path)
 
     def _make_long_dir(self):
         components = [self.getBuildArtifact("deep")] + ["d" * 80] * 3
diff --git a/lldb/test/API/functionalities/longpath/TestLongPath.py 
b/lldb/test/API/functionalities/longpath/TestLongPath.py
index 590d17f82945c..28e0df4859316 100644
--- a/lldb/test/API/functionalities/longpath/TestLongPath.py
+++ b/lldb/test/API/functionalities/longpath/TestLongPath.py
@@ -19,7 +19,7 @@ class LongPathTargetTestCase(TestBase):
     NO_DEBUG_INFO_TESTCASE = True
 
     def _long_path(self, path):
-        return "\\\\?\\" + os.path.abspath(path)
+        return lldbutil.get_extended_windows_path(path)
 
     def _normalize(self, path):
         if path.startswith("\\\\?\\"):
diff --git a/lldb/test/API/tools/lldb-dap/longpath/TestDAP_launch_longPath.py 
b/lldb/test/API/tools/lldb-dap/longpath/TestDAP_launch_longPath.py
index ebd0afe0f3483..d7c86b5a9a286 100644
--- a/lldb/test/API/tools/lldb-dap/longpath/TestDAP_launch_longPath.py
+++ b/lldb/test/API/tools/lldb-dap/longpath/TestDAP_launch_longPath.py
@@ -8,6 +8,7 @@
 
 import lldbdap_testcase
 from lldbsuite.test.decorators import *
+from lldbsuite.test import lldbutil
 
 MAX_PATH = 260
 
@@ -15,7 +16,7 @@
 @skipUnlessWindows
 class TestDAP_launch_longPath(lldbdap_testcase.DAPTestCaseBase):
     def _long_path(self, path):
-        return "\\\\?\\" + os.path.abspath(path)
+        return lldbutil.get_extended_windows_path(path)
 
     def _normalize(self, path):
         if path.startswith("\\\\?\\"):
diff --git a/lldb/test/Shell/helper/toolchain.py 
b/lldb/test/Shell/helper/toolchain.py
index c00985a8ef615..df20a4ae7af5e 100644
--- a/lldb/test/Shell/helper/toolchain.py
+++ b/lldb/test/Shell/helper/toolchain.py
@@ -55,13 +55,6 @@ def __init__(
         super().__init__(execute_external, extra_substitutions, 
preamble_commands)
 
     def execute(self, test, litConfig):
-        exec_path = test.getExecPath()
-        if platform.system() == "Windows" and len(exec_path) > 256:
-            litConfig.warning(
-                "Test path exceeds 256 characters (Windows MAX_PATH limit): "
-                + exec_path
-            )
-
         # Run each Shell test in a separate directory (on remote).
 
         # Find directory change command in %lldb substitution.

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to