From 1d8909ddb7bab40d54c2073fce4d5b76d8a15fb6 Mon Sep 17 00:00:00 2001
From: jeremyd2019 <github@jdrake.com>
Date: Fri, 1 Aug 2025 10:35:09 -0700
Subject: [PATCH] [LLVM][Support] Fix tests on Cygwin (#151417)

Cygwin returns -1 for `getconf(_SC_ARG_MAX)`, which makes
`llvm::sys::commandLineFitsWithinSystemLimits` always return true, so
skip the `ArgumentLimit` test in that case. Skip the
`ArgumentLimitWindows` and `ResponseFileWindows` tests on Cygwin also as
it doesn't suffer from the Windows limits either.

Cygwin requires the same `dllexport` annotation as Win32 in the
`DynamicLibrary` test, so add its preprocessor check to PipSqueak.h.

Cygwin's `getcwd` function does not fail with `ENOENT` if the current
working directory is unlinked. According to POSIX issue 8, this is not
required. Skip the `PhysicalFileSystemWorkingDirFailure` test on Cygwin
as it relies on this behavior.
---
 llvm/unittests/Support/CommandLineTest.cpp    | 22 +++++++++++++++----
 .../Support/DynamicLibrary/PipSqueak.h        |  2 +-
 .../Support/VirtualFileSystemTest.cpp         |  4 ++++
 3 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/llvm/unittests/Support/CommandLineTest.cpp b/llvm/unittests/Support/CommandLineTest.cpp
index 3df4107ebf..ad06ca91c2 100644
--- a/llvm/unittests/Support/CommandLineTest.cpp
+++ b/llvm/unittests/Support/CommandLineTest.cpp
@@ -28,6 +28,9 @@
 #include <fstream>
 #include <stdlib.h>
 #include <string>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
 
 using namespace llvm;
 using llvm::unittest::TempDir;
@@ -834,14 +837,23 @@ TEST(CommandLineTest, DefaultOptions) {
 }
 
 TEST(CommandLineTest, ArgumentLimit) {
-  std::string args(32 * 4096, 'a');
-  EXPECT_FALSE(llvm::sys::commandLineFitsWithinSystemLimits("cl", args.data()));
+#if HAVE_UNISTD_H && defined(_SC_ARG_MAX)
+  if (sysconf(_SC_ARG_MAX) != -1) {
+#endif
+    std::string args(32 * 4096, 'a');
+    EXPECT_FALSE(
+        llvm::sys::commandLineFitsWithinSystemLimits("cl", args.data()));
+#if HAVE_UNISTD_H && defined(_SC_ARG_MAX)
+  }
+#endif
   std::string args2(256, 'a');
   EXPECT_TRUE(llvm::sys::commandLineFitsWithinSystemLimits("cl", args2.data()));
 }
 
 TEST(CommandLineTest, ArgumentLimitWindows) {
-  if (!Triple(sys::getProcessTriple()).isOSWindows())
+  Triple processTriple(sys::getProcessTriple());
+  if (!processTriple.isOSWindows() ||
+      processTriple.isWindowsCygwinEnvironment())
     GTEST_SKIP();
   // We use 32000 as a limit for command line length. Program name ('cl'),
   // separating spaces and termination null character occupy 5 symbols.
@@ -854,7 +866,9 @@ TEST(CommandLineTest, ArgumentLimitWindows) {
 }
 
 TEST(CommandLineTest, ResponseFileWindows) {
-  if (!Triple(sys::getProcessTriple()).isOSWindows())
+  Triple processTriple(sys::getProcessTriple());
+  if (!processTriple.isOSWindows() ||
+      processTriple.isWindowsCygwinEnvironment())
     GTEST_SKIP();
 
   StackOption<std::string, cl::list<std::string>> InputFilenames(
diff --git a/llvm/unittests/Support/DynamicLibrary/PipSqueak.h b/llvm/unittests/Support/DynamicLibrary/PipSqueak.h
index 3eac1e0f64..dc069ca3d8 100644
--- a/llvm/unittests/Support/DynamicLibrary/PipSqueak.h
+++ b/llvm/unittests/Support/DynamicLibrary/PipSqueak.h
@@ -22,7 +22,7 @@
 #include <vector>
 #endif
 
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
 #define PIPSQUEAK_EXPORT __declspec(dllexport)
 #elif defined(__MVS__)
 #define PIPSQUEAK_EXPORT __attribute__((__visibility__("default")))
diff --git a/llvm/unittests/Support/VirtualFileSystemTest.cpp b/llvm/unittests/Support/VirtualFileSystemTest.cpp
index eb590e474c..97b0550c0d 100644
--- a/llvm/unittests/Support/VirtualFileSystemTest.cpp
+++ b/llvm/unittests/Support/VirtualFileSystemTest.cpp
@@ -558,6 +558,10 @@ TEST(VirtualFileSystemTest, PhysicalFileSystemWorkingDirFailure) {
     // Some platforms (e.g. Solaris) disallow removal of the working directory.
     GTEST_SKIP() << "test requires deletion of working directory";
 
+#ifdef __CYGWIN__
+  GTEST_SKIP() << "Cygwin getcwd succeeds with unlinked working directory";
+#endif
+
   // Verify that we still get two separate working directories.
   auto FS1 = vfs::createPhysicalFileSystem();
   auto FS2 = vfs::createPhysicalFileSystem();
-- 
2.51.0.windows.1

