summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2023-10-03 19:19:44 (GMT)
committerBrad King <brad.king@kitware.com>2023-10-03 20:06:46 (GMT)
commit7ac696549a8608490e871ee77efe4086daf28add (patch)
tree57cce92f87b2cfa9c747661d61cd057591e6556b
parent8bd2c8d1fdd5b2dad9e65835a9c704ebe9b7371a (diff)
downloadCMake-7ac696549a8608490e871ee77efe4086daf28add.zip
CMake-7ac696549a8608490e871ee77efe4086daf28add.tar.gz
CMake-7ac696549a8608490e871ee77efe4086daf28add.tar.bz2
cxxmodules: Fix CMP0155 NEW behavior when C++ compile features are not known
With CMP0155 NEW behavior, we scan C++ sources in targets using C++ 20, i.e., in which the `cxx_std_20` feature is available. However, our check for C++ feature availability may incorrectly succeed in two cases: * MSVC versions from VS 2013 do not model C++ standard levels, so we assume all features are available as a heuristic to let projects at least try compiling with them. * During ABI detection the `CMAKE_CXX20_COMPILE_FEATURES` variable is not populated so we assume all features are available, knowing that our ABI detection project does not need them. For purposes of detecting targets using C++ 20, we do not want to assume `cxx_std_20` is available, so verify that we really know it is.
-rw-r--r--Source/cmGeneratorTarget.cxx29
1 files changed, 18 insertions, 11 deletions
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 96fcf7e..422d927 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -9093,20 +9093,27 @@ cmGeneratorTarget::Cxx20SupportLevel cmGeneratorTarget::HaveCxxModuleSupport(
if (!state->GetLanguageEnabled("CXX")) {
return Cxx20SupportLevel::MissingCxx;
}
+
cmValue standardDefault =
- this->Target->GetMakefile()->GetDefinition("CMAKE_CXX_STANDARD_DEFAULT");
- if (standardDefault && !standardDefault->empty()) {
- cmStandardLevelResolver standardResolver(this->Makefile);
- if (!standardResolver.HaveStandardAvailable(this, "CXX", config,
- "cxx_std_20")) {
- return Cxx20SupportLevel::NoCxx20;
- }
+ this->Makefile->GetDefinition("CMAKE_CXX_STANDARD_DEFAULT");
+ if (!standardDefault || standardDefault->empty()) {
+ // We do not know any meaningful C++ standard levels for this compiler.
+ return Cxx20SupportLevel::NoCxx20;
+ }
+
+ cmStandardLevelResolver standardResolver(this->Makefile);
+ if (!standardResolver.HaveStandardAvailable(this, "CXX", config,
+ "cxx_std_20") ||
+ // During the ABI detection step we do not know the compiler's features.
+ // HaveStandardAvailable may return true as a fallback, but in this code
+ // path we do not want to assume C++ 20 is available.
+ this->Makefile->GetDefinition("CMAKE_CXX20_COMPILE_FEATURES")
+ .IsEmpty()) {
+ return Cxx20SupportLevel::NoCxx20;
}
- // Else, an empty CMAKE_CXX_STANDARD_DEFAULT means CMake does not detect and
- // set a default standard level for this compiler, so assume all standards
- // are available.
+
cmValue scandepRule =
- this->Target->GetMakefile()->GetDefinition("CMAKE_CXX_SCANDEP_SOURCE");
+ this->Makefile->GetDefinition("CMAKE_CXX_SCANDEP_SOURCE");
if (!scandepRule) {
return Cxx20SupportLevel::MissingRule;
}