diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 99525b00239a4..09406adcb5b87 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 `_) + 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 9c00fa50bb955..6110c6d6ea195 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>; + 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 94c184435ae14..5d77f69ae703f 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3724,20 +3724,10 @@ bool Driver::getDefaultModuleCachePath(SmallVectorImpl &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); + + // -fdelayed-template-parsing is default 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, + // 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 -fdelayed-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 0000000000000..7af9b2447bb4b --- /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