[llvm] Fix ExecuteAndWait with empty environment on Windows (PR #158719)

Hiroshi Yamauchi via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 15 14:06:24 PDT 2025


https://github.com/hjyamauchi updated https://github.com/llvm/llvm-project/pull/158719

>From 971644422da3211b48f6dc5d0d93e5f0ad7e660f Mon Sep 17 00:00:00 2001
From: Hiroshi Yamauchi <hjyamauchi at gmail.com>
Date: Mon, 15 Sep 2025 12:17:19 -0700
Subject: [PATCH] Fix ExecuteAndWait with empty environment on Windows

CreateProcessW requires that the environemnt block to be always double
null-terminated even with an empty environemnt.

https://learn.microsoft.com/en-us/windows/win32/procthread/environment-variables

The attached test fails this way without the fix.

C:\Users\hiroshi\upstream\llvm-project\llvm\unittests\Support\ProgramTest.cpp(697): error: Value of: ExecutionFailed
  Actual: true
  Expected: false
  Couldn't execute program 'C:\Users\hiroshi\upstream\llvm-project\build\unittests\Support\SupportTests.exe': The parameter is incorrect.  (0x57)
---
 llvm/lib/Support/Windows/Program.inc   |  4 ++++
 llvm/unittests/Support/ProgramTest.cpp | 18 ++++++++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/llvm/lib/Support/Windows/Program.inc b/llvm/lib/Support/Windows/Program.inc
index 799af5559966c..d8d2e181aa337 100644
--- a/llvm/lib/Support/Windows/Program.inc
+++ b/llvm/lib/Support/Windows/Program.inc
@@ -220,6 +220,10 @@ static bool Execute(ProcessInfo &PI, StringRef Program,
       llvm::append_range(EnvBlock, EnvString);
       EnvBlock.push_back(0);
     }
+    // If an empty environment (*Env is size zero), we need to
+    // terminate with two nulls.
+    if (Env->size() == 0)
+      EnvBlock.push_back(0);
     EnvBlock.push_back(0);
   }
 
diff --git a/llvm/unittests/Support/ProgramTest.cpp b/llvm/unittests/Support/ProgramTest.cpp
index d30bf458f233c..eac0246d8c59e 100644
--- a/llvm/unittests/Support/ProgramTest.cpp
+++ b/llvm/unittests/Support/ProgramTest.cpp
@@ -680,4 +680,22 @@ TEST_F(ProgramEnvTest, TestExecuteWithNoStacktraceHandler) {
   ASSERT_EQ(0, RetCode);
 }
 
+TEST_F(ProgramEnvTest, TestExecuteEmptyEnvironment) {
+  using namespace llvm::sys;
+
+  std::string Executable =
+      sys::fs::getMainExecutable(TestMainArgv0, &ProgramTestStringArg1);
+  StringRef argv[] = {
+      Executable,
+      "--gtest_filter=" // A null invocation to avoid infinite recursion
+  };
+
+  std::string Error;
+  bool ExecutionFailed;
+  int RetCode = ExecuteAndWait(Executable, argv, ArrayRef<StringRef>{}, {}, 0,
+                               0, &Error, &ExecutionFailed);
+  EXPECT_FALSE(ExecutionFailed) << Error;
+  ASSERT_EQ(0, RetCode);
+}
+
 } // end anonymous namespace



More information about the llvm-commits mailing list