[clang] ab8f622 - [DebugInfo] Fix file path separator when targeting windows.

Zequan Wu via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 17 10:07:48 PDT 2023


Author: Zequan Wu
Date: 2023-04-17T13:07:42-04:00
New Revision: ab8f622c79b27bc606da043e8dcbd417b8ade725

URL: https://github.com/llvm/llvm-project/commit/ab8f622c79b27bc606da043e8dcbd417b8ade725
DIFF: https://github.com/llvm/llvm-project/commit/ab8f622c79b27bc606da043e8dcbd417b8ade725.diff

LOG: [DebugInfo] Fix file path separator when targeting windows.

This fixes two problems:

1. When crossing compiling for windows on linux, source file path in debug info is concatenated with directory by host native separator ('/'). For windows local build, they are concatenated by '\'. This causes non-determinism bug.

  The solution here is to let `LangOptions.UseTargetPathSeparator` to control if we should use host native separator or not.

2. Objectfile path in CodeView also uses host native separator when generated.

 It's fixed by changing the path separator in `/Fo` to '\' if the path is not an absolute path when adding the `-object-file-name=` flag.

Reviewed By: hans

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

Added: 
    clang/test/CodeGen/debug-info-slash.c

Modified: 
    clang/include/clang/Basic/LangOptions.h
    clang/lib/CodeGen/CGDebugInfo.cpp
    clang/lib/Driver/ToolChains/Clang.cpp
    clang/test/Driver/cl-outputs.c
    llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index b8c223b28f8a1..1c98e28231b57 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -479,9 +479,9 @@ class LangOptions : public LangOptionsBase {
   /// The seed used by the randomize structure layout feature.
   std::string RandstructSeed;
 
-  /// Indicates whether the __FILE__ macro should use the target's
-  /// platform-specific file separator or whether it should use the build
-  /// environment's platform-specific file separator.
+  /// Indicates whether to use target's platform-specific file separator when
+  /// __FILE__ macro is used and when concatenating filename with directory or
+  /// to use build environment environment's platform-specific file separator.
   ///
   /// The plaform-specific path separator is the backslash(\) for Windows and
   /// forward slash (/) elsewhere.

diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index cd0fece34502a..5100d6c65baa4 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -528,6 +528,7 @@ void CGDebugInfo::CreateCompileUnit() {
   // Get absolute path name.
   SourceManager &SM = CGM.getContext().getSourceManager();
   auto &CGO = CGM.getCodeGenOpts();
+  const LangOptions &LO = CGM.getLangOpts();
   std::string MainFileName = CGO.MainFileName;
   if (MainFileName.empty())
     MainFileName = "<stdin>";
@@ -542,9 +543,15 @@ void CGDebugInfo::CreateCompileUnit() {
     MainFileDir = std::string(MainFile->getDir().getName());
     if (!llvm::sys::path::is_absolute(MainFileName)) {
       llvm::SmallString<1024> MainFileDirSS(MainFileDir);
-      llvm::sys::path::append(MainFileDirSS, MainFileName);
-      MainFileName =
-          std::string(llvm::sys::path::remove_leading_dotslash(MainFileDirSS));
+      llvm::sys::path::Style Style =
+          LO.UseTargetPathSeparator
+              ? (CGM.getTarget().getTriple().isOSWindows()
+                     ? llvm::sys::path::Style::windows_backslash
+                     : llvm::sys::path::Style::posix)
+              : llvm::sys::path::Style::native;
+      llvm::sys::path::append(MainFileDirSS, Style, MainFileName);
+      MainFileName = std::string(
+          llvm::sys::path::remove_leading_dotslash(MainFileDirSS, Style));
     }
     // If the main file name provided is identical to the input file name, and
     // if the input file is a preprocessed source, use the module name for
@@ -560,7 +567,6 @@ void CGDebugInfo::CreateCompileUnit() {
   }
 
   llvm::dwarf::SourceLanguage LangTag;
-  const LangOptions &LO = CGM.getLangOpts();
   if (LO.CPlusPlus) {
     if (LO.ObjC)
       LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;

diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 65238830a57b6..be577239ab04d 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -563,6 +563,16 @@ static void addDebugObjectName(const ArgList &Args, ArgStringList &CmdArgs,
     // Make the path absolute in the debug infos like MSVC does.
     llvm::sys::fs::make_absolute(ObjFileNameForDebug);
   }
+  // If the object file name is a relative path, then always use Windows
+  // backslash style as -object-file-name is used for embedding object file path
+  // in codeview and it can only be generated when targeting on Windows.
+  // Otherwise, just use native absolute path.
+  llvm::sys::path::Style Style =
+      llvm::sys::path::is_absolute(ObjFileNameForDebug)
+          ? llvm::sys::path::Style::native
+          : llvm::sys::path::Style::windows_backslash;
+  llvm::sys::path::remove_dots(ObjFileNameForDebug, /*remove_dot_dot=*/true,
+                               Style);
   CmdArgs.push_back(
       Args.MakeArgString(Twine("-object-file-name=") + ObjFileNameForDebug));
 }

diff  --git a/clang/test/CodeGen/debug-info-slash.c b/clang/test/CodeGen/debug-info-slash.c
new file mode 100644
index 0000000000000..56e51c09e5b0e
--- /dev/null
+++ b/clang/test/CodeGen/debug-info-slash.c
@@ -0,0 +1,6 @@
+// RUN: %clang -target x86_64-pc-win32  -ffile-reproducible -emit-llvm -S -g %s -o - | FileCheck --check-prefix=WIN %s
+// RUN: %clang -target x86_64-linux-gnu  -ffile-reproducible -emit-llvm -S -g %s -o - | FileCheck --check-prefix=LINUX %s
+int main() { return 0; }
+
+// WIN:   !DIFile(filename: "{{.*}}\\debug-info-slash.c"
+// LINUX: !DIFile(filename: "{{.*}}/debug-info-slash.c"

diff  --git a/clang/test/Driver/cl-outputs.c b/clang/test/Driver/cl-outputs.c
index 972e4499dbd9c..e7eb6f56563e0 100644
--- a/clang/test/Driver/cl-outputs.c
+++ b/clang/test/Driver/cl-outputs.c
@@ -294,3 +294,12 @@
 // RUN: %clang_cl /P /Fifoo.x /obar.x -### -- %s 2>&1 | FileCheck -check-prefix=FioRACE2 %s
 // FioRACE2: "-E"
 // FioRACE2: "-o" "foo.x"
+
+// RUN: %clang_cl /Z7 /Foa.obj -### -- %s 2>&1 | FileCheck -check-prefix=ABSOLUTE_OBJPATH %s
+// ABSOLUTE_OBJPATH: "-object-file-name={{.*}}a.obj"
+
+// RUN: %clang_cl -fdebug-compilation-dir=. /Z7 /Foa.obj -### -- %s 2>&1 | FileCheck -check-prefix=RELATIVE_OBJPATH1 %s
+// RELATIVE_OBJPATH1: "-object-file-name=a.obj"
+
+// RUN: %clang_cl -fdebug-compilation-dir=. /Z7 /Fofoo/a.obj -### -- %s 2>&1 | FileCheck -check-prefix=RELATIVE_OBJPATH2 %s
+// RELATIVE_OBJPATH2: "-object-file-name=foo\\a.obj"

diff  --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 86cdd11ebd17e..5aceb33f00dc7 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -791,7 +791,6 @@ void CodeViewDebug::emitObjName() {
     // Don't emit the filename if we're writing to stdout or to /dev/null.
     PathRef = {};
   } else {
-    llvm::sys::path::remove_dots(PathStore, /*remove_dot_dot=*/true);
     PathRef = PathStore;
   }
 


        


More information about the cfe-commits mailing list