[llvm] r334602 - Do not enforce absolute path argv0 in windows

Hans Wennborg via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 13 07:29:26 PDT 2018


Author: hans
Date: Wed Jun 13 07:29:26 2018
New Revision: 334602

URL: http://llvm.org/viewvc/llvm-project?rev=334602&view=rev
Log:
Do not enforce absolute path argv0 in windows

Even if we support no-canonical-prefix on
clang-cl(https://reviews.llvm.org/D47480), argv0 becomes absolute path
in clang-cl and that embeds absolute path in /showIncludes.

This patch removes such full path normalization from InitLLVM on
windows, and that removes absolute path from clang-cl output
(obj/stdout/stderr) when debug flag is disabled.

Patch by Takuto Ikuta!

Differential Revision https://reviews.llvm.org/D47578

Modified:
    llvm/trunk/lib/Support/Windows/Process.inc
    llvm/trunk/unittests/Support/CommandLineTest.cpp

Modified: llvm/trunk/lib/Support/Windows/Process.inc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/Process.inc?rev=334602&r1=334601&r2=334602&view=diff
==============================================================================
--- llvm/trunk/lib/Support/Windows/Process.inc (original)
+++ llvm/trunk/lib/Support/Windows/Process.inc Wed Jun 13 07:29:26 2018
@@ -209,55 +209,65 @@ static std::error_code WildcardExpand(co
   return ec;
 }
 
-static std::error_code ExpandShortFileName(const wchar_t *Arg,
-                                           SmallVectorImpl<const char *> &Args,
-                                           BumpPtrAllocator &Alloc) {
-  SmallVector<wchar_t, MAX_PATH> LongPath;
-  DWORD Length = GetLongPathNameW(Arg, LongPath.data(), LongPath.capacity());
+static std::error_code GetExecutableName(SmallVectorImpl<char> &Filename) {
+  // The first argument may contain just the name of the executable (e.g.,
+  // "clang") rather than the full path, so swap it with the full path.
+  wchar_t ModuleName[MAX_PATH];
+  size_t Length = ::GetModuleFileNameW(NULL, ModuleName, MAX_PATH);
+  if (Length == 0 || Length == MAX_PATH) {
+    return mapWindowsError(GetLastError());
+  }
+
+  // If the first argument is a shortened (8.3) name (which is possible even
+  // if we got the module name), the driver will have trouble distinguishing it
+  // (e.g., clang.exe v. clang++.exe), so expand it now.
+  Length = GetLongPathNameW(ModuleName, ModuleName, MAX_PATH);
   if (Length == 0)
     return mapWindowsError(GetLastError());
-  if (Length > LongPath.capacity()) {
+  if (Length > MAX_PATH) {
     // We're not going to try to deal with paths longer than MAX_PATH, so we'll
     // treat this as an error.  GetLastError() returns ERROR_SUCCESS, which
     // isn't useful, so we'll hardcode an appropriate error value.
     return mapWindowsError(ERROR_INSUFFICIENT_BUFFER);
   }
-  LongPath.set_size(Length);
-  return ConvertAndPushArg(LongPath.data(), Args, Alloc);
+
+  std::error_code EC = windows::UTF16ToUTF8(ModuleName, Length, Filename);
+  if (EC)
+    return EC;
+
+  StringRef Base = sys::path::filename(Filename.data());
+  Filename.assign(Base.begin(), Base.end());
+  return std::error_code();
 }
 
 std::error_code
 windows::GetCommandLineArguments(SmallVectorImpl<const char *> &Args,
                                  BumpPtrAllocator &Alloc) {
   int ArgCount;
-  wchar_t **UnicodeCommandLine =
-      CommandLineToArgvW(GetCommandLineW(), &ArgCount);
+  std::unique_ptr<wchar_t *[], decltype(&LocalFree)> UnicodeCommandLine{
+    CommandLineToArgvW(GetCommandLineW(), &ArgCount), &LocalFree};
   if (!UnicodeCommandLine)
     return mapWindowsError(::GetLastError());
 
-  Args.reserve(ArgCount);
-  std::error_code ec;
-
-  // The first argument may contain just the name of the executable (e.g.,
-  // "clang") rather than the full path, so swap it with the full path.
-  wchar_t ModuleName[MAX_PATH];
-  int Length = ::GetModuleFileNameW(NULL, ModuleName, MAX_PATH);
-  if (0 < Length && Length < MAX_PATH)
-    UnicodeCommandLine[0] = ModuleName;
+  std::error_code EC;
 
-  // If the first argument is a shortened (8.3) name (which is possible even
-  // if we got the module name), the driver will have trouble distinguishing it
-  // (e.g., clang.exe v. clang++.exe), so expand it now.
-  ec = ExpandShortFileName(UnicodeCommandLine[0], Args, Alloc);
+  Args.reserve(ArgCount);
 
-  for (int i = 1; i < ArgCount && !ec; ++i) {
-    ec = WildcardExpand(UnicodeCommandLine[i], Args, Alloc);
-    if (ec)
-      break;
+  for (int I = 0; I < ArgCount; ++I) {
+    EC = WildcardExpand(UnicodeCommandLine[I], Args, Alloc);
+    if (EC)
+      return EC;
   }
 
-  LocalFree(UnicodeCommandLine);
-  return ec;
+  SmallVector<char, MAX_PATH> Arg0(Args[0], Args[0] + strlen(Args[0]));
+  SmallVector<char, MAX_PATH> Filename;
+  sys::path::remove_filename(Arg0);
+  EC = GetExecutableName(Filename);
+  if (EC)
+    return EC;
+  sys::path::append(Arg0, Filename);
+  Args[0] = AllocateString(Arg0, Alloc);
+  return std::error_code();
 }
 
 std::error_code Process::FixupStandardFileDescriptors() {

Modified: llvm/trunk/unittests/Support/CommandLineTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/CommandLineTest.cpp?rev=334602&r1=334601&r2=334602&view=diff
==============================================================================
--- llvm/trunk/unittests/Support/CommandLineTest.cpp (original)
+++ llvm/trunk/unittests/Support/CommandLineTest.cpp Wed Jun 13 07:29:26 2018
@@ -13,6 +13,7 @@
 #include "llvm/ADT/Triple.h"
 #include "llvm/Config/config.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/InitLLVM.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
 #include "llvm/Support/StringSaver.h"
@@ -821,4 +822,22 @@ TEST(CommandLineTest, PositionalEatArgsE
   EXPECT_TRUE(Errs.empty());
 }
 
+#ifdef _WIN32
+TEST(CommandLineTest, GetCommandLineArguments) {
+  int argc = __argc;
+  char **argv = __argv;
+
+  // GetCommandLineArguments is called in InitLLVM.
+  llvm::InitLLVM X(argc, argv);
+
+  EXPECT_EQ(llvm::sys::path::is_absolute(argv[0]),
+            llvm::sys::path::is_absolute(__argv[0]));
+
+  EXPECT_TRUE(llvm::sys::path::filename(argv[0])
+              .equals_lower("supporttests.exe"))
+      << "Filename of test executable is "
+      << llvm::sys::path::filename(argv[0]);
+}
+#endif
+
 }  // anonymous namespace




More information about the llvm-commits mailing list