https://github.com/petrhosek created https://github.com/llvm/llvm-project/pull/238235
Guard FlagForCRT against being empty in ProcessVSRuntimeLibrary, run ProcessVSRuntimeLibrary when -fms-omit-default-lib is passed in non-CL MSVC mode, and select the matching CRT library (-defaultlib:msvcrt, msvcrtd, libcmt, libcmtd) or omit default libraries when -nodefaultlibs or -fms-omit-default-lib is specified. >From e9445ba1f6af937f91a33ecfe201fc3f098e10e2 Mon Sep 17 00:00:00 2001 From: Petr Hosek <[email protected]> Date: Sat, 31 Oct 2026 17:48:50 -0700 Subject: [PATCH] [Driver] Respect CRT flags and -fms-omit-default-lib in MSVC mode Guard FlagForCRT against being empty in ProcessVSRuntimeLibrary, run ProcessVSRuntimeLibrary when -fms-omit-default-lib is passed in non-CL MSVC mode, and select the matching CRT library (-defaultlib:msvcrt, msvcrtd, libcmt, libcmtd) or omit default libraries when -nodefaultlibs or -fms-omit-default-lib is specified. --- clang/lib/Driver/ToolChains/Clang.cpp | 6 ++++-- clang/lib/Driver/ToolChains/MSVC.cpp | 16 ++++++++++++++-- clang/test/Driver/cl-runtime-flags.c | 2 ++ clang/test/Driver/msvc-link.c | 18 ++++++++++++++++++ 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index df6022c204425b..72e44c293986e0 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5149,7 +5149,8 @@ static void ProcessVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args, if (Args.hasArg(options::OPT_fms_omit_default_lib)) { CmdArgs.push_back("-D_VC_NODEFAULTLIB"); } else { - CmdArgs.push_back(FlagForCRT.data()); + if (!FlagForCRT.empty()) + CmdArgs.push_back(FlagForCRT.data()); // This provides POSIX compatibility (maps 'open' to '_open'), which most // users want. The /Za flag to cl.exe turns this off, but it's not @@ -7669,7 +7670,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(MSAnonOpt); if (Triple.isWindowsMSVCEnvironment() && !D.IsCLMode() && - Args.hasArg(options::OPT_fms_runtime_lib_EQ)) + Args.hasArg(options::OPT_fms_runtime_lib_EQ, + options::OPT_fms_omit_default_lib)) ProcessVSRuntimeLibrary(getToolChain(), Args, CmdArgs); // Handle -fgcc-version, if present. diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp index 25ea64a4ba5055..db4327acb1edd5 100644 --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -122,8 +122,20 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) && !C.getDriver().IsCLMode() && !C.getDriver().IsFlangMode()) { - CmdArgs.push_back("-defaultlib:libcmt"); - CmdArgs.push_back("-defaultlib:oldnames"); + if (!Args.hasArg(options::OPT_nodefaultlibs, + options::OPT_fms_omit_default_lib)) { + StringRef CRT = "libcmt"; + if (const Arg *A = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) { + CRT = llvm::StringSwitch<StringRef>(A->getValue()) + .Case("dll", "msvcrt") + .Case("dll_dbg", "msvcrtd") + .Case("static", "libcmt") + .Case("static_dbg", "libcmtd") + .Default("libcmt"); + } + CmdArgs.push_back(Args.MakeArgString("-defaultlib:" + CRT)); + CmdArgs.push_back("-defaultlib:oldnames"); + } // SYCL: Add runtime library for clang (non-clang-cl) with MSVC target. // For clang-cl, --dependent-lib is used at compiler stage instead. diff --git a/clang/test/Driver/cl-runtime-flags.c b/clang/test/Driver/cl-runtime-flags.c index 2a6151e08c046f..ca807e81f94dd3 100644 --- a/clang/test/Driver/cl-runtime-flags.c +++ b/clang/test/Driver/cl-runtime-flags.c @@ -97,6 +97,8 @@ // RUN: %clang_cl -### /Zl -- %s 2>&1 | FileCheck -check-prefix=CHECK-MTZl %s // RUN: %clang_cl -### /MT /Zl -- %s 2>&1 | FileCheck -check-prefix=CHECK-MTZl %s +// RUN: %clang -### --target=x86_64-windows-msvc -fms-omit-default-lib -- %s \ +// RUN: 2>&1 | FileCheck -check-prefix=CHECK-MTZl %s // RUN: %clang -### --target=x86_64-windows-msvc -fms-runtime-lib=static \ // RUN: -fms-omit-default-lib -- %s 2>&1 | FileCheck \ // RUN: -check-prefix=CHECK-MTZl %s diff --git a/clang/test/Driver/msvc-link.c b/clang/test/Driver/msvc-link.c index fc7a18014da735..0424ff99dd0aa4 100644 --- a/clang/test/Driver/msvc-link.c +++ b/clang/test/Driver/msvc-link.c @@ -14,6 +14,24 @@ // DLL-SAME: "-defaultlib:libcmt" "-defaultlib:oldnames" // DLL-SAME: "-nologo" "-dll" +// RUN: %clang --target=i686-pc-windows-msvc -fms-runtime-lib=dll -fuse-ld=link -### %s 2>&1 | FileCheck --check-prefix=RUNTIME-DLL %s +// RUNTIME-DLL: link.exe" +// RUNTIME-DLL-SAME: "-defaultlib:msvcrt" "-defaultlib:oldnames" + +// RUN: %clang --target=i686-pc-windows-msvc -fms-runtime-lib=dll_dbg -fuse-ld=link -### %s 2>&1 | FileCheck --check-prefix=RUNTIME-DLL-DBG %s +// RUNTIME-DLL-DBG: link.exe" +// RUNTIME-DLL-DBG-SAME: "-defaultlib:msvcrtd" "-defaultlib:oldnames" + +// RUN: %clang --target=i686-pc-windows-msvc -fms-runtime-lib=static_dbg -fuse-ld=link -### %s 2>&1 | FileCheck --check-prefix=RUNTIME-STATIC-DBG %s +// RUNTIME-STATIC-DBG: link.exe" +// RUNTIME-STATIC-DBG-SAME: "-defaultlib:libcmtd" "-defaultlib:oldnames" + +// RUN: %clang --target=i686-pc-windows-msvc -nodefaultlibs -fuse-ld=link -### %s 2>&1 | FileCheck --check-prefix=NODEFAULTLIBS %s +// RUN: %clang --target=i686-pc-windows-msvc -fms-omit-default-lib -fuse-ld=link -### %s 2>&1 | FileCheck --check-prefix=NODEFAULTLIBS %s +// NODEFAULTLIBS: link.exe" +// NODEFAULTLIBS-NOT: "-defaultlib: + + // RUN: %clang_cl /Brepro -fuse-ld=link -### -- %s 2>&1 | FileCheck --check-prefix=REPRO %s // REPRO: link.exe" // REPRO-SAME: "-out:msvc-link.exe" _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
