[clang] [C++20] [Modules] [Driver] Don't enable -fdelayed-template-parsing by default on windows with C++20 modules (PR #69431)
Chuanqi Xu via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 20 06:55:29 PDT 2023
https://github.com/ChuanqiXu9 updated https://github.com/llvm/llvm-project/pull/69431
>From 076f2ea9de7d0f979431363b5426931239c7c494 Mon Sep 17 00:00:00 2001
From: Chuanqi Xu <yedeng.yd at linux.alibaba.com>
Date: Wed, 18 Oct 2023 15:58:03 +0800
Subject: [PATCH] [C++20] [Modules] [Driver] Don't enable
-fdelayed-template-parsing by default on windows after c++20
There are already 3 issues about the broken state of
-fdelayed-template-parsing and C++20 modules:
- https://github.com/llvm/llvm-project/issues/61068
- https://github.com/llvm/llvm-project/issues/64810
- https://github.com/llvm/llvm-project/issues/65027
The problem is more complex than I thought. I am not sure how to fix it
properly now. Given the complexities and -fdelayed-template-parsing is
actually an extension to support old MS codes, I think it may make sense
to not enable the -fdelayed-template-parsing option by default with
C++20 modules to give more user friendly experience. Users who still want
-fdelayed-template-parsing can specify it explicitly.
Given the discussion in https://github.com/llvm/llvm-project/pull/69551,
we decide to not enable -fdelayed-template-parsing by default on windows
after c++20
---
clang/docs/ReleaseNotes.rst | 4 ++
.../clang/Basic/DiagnosticDriverKinds.td | 4 ++
clang/lib/Driver/ToolChains/Clang.cpp | 54 +++++++++++--------
.../cl-delayed-template-parsing-cxx20.cpp | 10 ++++
4 files changed, 51 insertions(+), 21 deletions(-)
create mode 100644 clang/test/Driver/cl-delayed-template-parsing-cxx20.cpp
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 99525b00239a4ca..09406adcb5b87f2 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -100,6 +100,10 @@ C++ Specific Potentially Breaking Changes
system headers and macros. It will be turned into a hard (non-downgradable)
error in the next Clang release.
+- The flag `-fdelayed-template-parsing` won't be enabled by default with C++20
+ when targetting MSVC to match the behavior of MSVC.
+ (`MSVC Docs <https://learn.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance?view=msvc-170>`_)
+
ABI Changes in This Version
---------------------------
- Following the SystemV ABI for x86-64, ``__int128`` arguments will no longer
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 9c00fa50bb95580..6110c6d6ea195b8 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -527,6 +527,10 @@ def err_test_module_file_extension_format : Error<
def err_drv_module_output_with_multiple_arch : Error<
"option '-fmodule-output' can't be used with multiple arch options">;
+def warn_drv_delayed_template_parsing_after_cxx20 : Warning<
+ "-fdelayed-template-parsing is deprecated after C++20">,
+ InGroup<DiagGroup<"delayed-template-parsing-in-cxx20">>;
+
def err_drv_extract_api_wrong_kind : Error<
"header file '%0' input '%1' does not match the type of prior input "
"in api extraction; use '-x %2' to override">;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 94c184435ae14de..cf1157c9ab4716f 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3724,20 +3724,10 @@ bool Driver::getDefaultModuleCachePath(SmallVectorImpl<char> &Result) {
static bool RenderModulesOptions(Compilation &C, const Driver &D,
const ArgList &Args, const InputInfo &Input,
- const InputInfo &Output, const Arg *Std,
+ const InputInfo &Output, bool HaveStd20,
ArgStringList &CmdArgs) {
bool IsCXX = types::isCXX(Input.getType());
- // FIXME: Find a better way to determine whether the input has standard c++
- // modules support by default.
- bool HaveStdCXXModules =
- IsCXX && Std &&
- (Std->containsValue("c++2a") || Std->containsValue("gnu++2a") ||
- Std->containsValue("c++20") || Std->containsValue("gnu++20") ||
- Std->containsValue("c++2b") || Std->containsValue("gnu++2b") ||
- Std->containsValue("c++23") || Std->containsValue("gnu++23") ||
- Std->containsValue("c++2c") || Std->containsValue("gnu++2c") ||
- Std->containsValue("c++26") || Std->containsValue("gnu++26") ||
- Std->containsValue("c++latest") || Std->containsValue("gnu++latest"));
+ bool HaveStdCXXModules = IsCXX && HaveStd20;
bool HaveModules = HaveStdCXXModules;
// -fmodules enables the use of precompiled modules (off by default).
@@ -6842,14 +6832,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
(!IsWindowsMSVC || IsMSVC2015Compatible)))
CmdArgs.push_back("-fno-threadsafe-statics");
- // -fno-delayed-template-parsing is default, except when targeting MSVC.
- // Many old Windows SDK versions require this to parse.
- // FIXME: MSVC introduced /Zc:twoPhase- to disable this behavior in their
- // compiler. We should be able to disable this by default at some point.
- if (Args.hasFlag(options::OPT_fdelayed_template_parsing,
- options::OPT_fno_delayed_template_parsing, IsWindowsMSVC))
- CmdArgs.push_back("-fdelayed-template-parsing");
-
// -fgnu-keywords default varies depending on language; only pass if
// specified.
Args.AddLastArg(CmdArgs, options::OPT_fgnu_keywords,
@@ -6870,8 +6852,38 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_finline_max_stacksize_EQ);
+ // FIXME: Find a better way to determine whether we are in C++20.
+ bool HaveCxx20 =
+ Std &&
+ (Std->containsValue("c++2a") || Std->containsValue("gnu++2a") ||
+ Std->containsValue("c++20") || Std->containsValue("gnu++20") ||
+ Std->containsValue("c++2b") || Std->containsValue("gnu++2b") ||
+ Std->containsValue("c++23") || Std->containsValue("gnu++23") ||
+ Std->containsValue("c++2c") || Std->containsValue("gnu++2c") ||
+ Std->containsValue("c++26") || Std->containsValue("gnu++26") ||
+ Std->containsValue("c++latest") || Std->containsValue("gnu++latest"));
bool HaveModules =
- RenderModulesOptions(C, D, Args, Input, Output, Std, CmdArgs);
+ RenderModulesOptions(C, D, Args, Input, Output, HaveCxx20, CmdArgs);
+
+ // -fno-delayed-template-parsing is default, except when targeting MSVC.
+ // Many old Windows SDK versions require this to parse.
+ //
+ // According to
+ // https://learn.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance?view=msvc-170,
+ // the MSVC actually defaults to -fno-delayed-template-parsing (/Zc:twoPhase-
+ // with MSVC CLI) if using C++20. So we match the behavior with MSVC here to
+ // not enable -fno-delayed-template-parsing by default after C++20.
+ //
+ // FIXME: Given -fdelayed-template-parsing is a source of bugs, we should be
+ // able to disable this by default at some point.
+ if (Args.hasFlag(options::OPT_fdelayed_template_parsing,
+ options::OPT_fno_delayed_template_parsing,
+ IsWindowsMSVC && !HaveCxx20)) {
+ if (HaveCxx20)
+ D.Diag(clang::diag::warn_drv_delayed_template_parsing_after_cxx20);
+
+ CmdArgs.push_back("-fdelayed-template-parsing");
+ }
if (Args.hasFlag(options::OPT_fpch_validate_input_files_content,
options::OPT_fno_pch_validate_input_files_content, false))
diff --git a/clang/test/Driver/cl-delayed-template-parsing-cxx20.cpp b/clang/test/Driver/cl-delayed-template-parsing-cxx20.cpp
new file mode 100644
index 000000000000000..7af9b2447bb4b0d
--- /dev/null
+++ b/clang/test/Driver/cl-delayed-template-parsing-cxx20.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cl -### -- %s 2>&1 | FileCheck %s --check-prefix=PRE-CXX20
+// RUN: %clang_cl -std:c++20 -### -- %s 2>&1 | FileCheck %s
+// RUN: %clang_cl -std:c++20 -### -fdelayed-template-parsing -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-EXPLICIT
+
+// PRE-CXX20: -fdelayed-template-parsing
+
+// CHECK-NOT: -fdelayed-template-parsing
+
+// CHECK-EXPLICIT: warning: -fdelayed-template-parsing is deprecated after C++20
+// CHECK-EXPLICIT: -fdelayed-template-parsing
More information about the cfe-commits
mailing list