Merge topic 'msvc-runtime-checks'

2b2344b412 MSVC: Add abstraction for runtime checks
49dcd1ce5d Help: Fix MSVC_DEBUG_INFORMATION_FORMAT description of example
2f8e643d9d CMP0141: Fix documentation copied from CMP0091

Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Alex <leha-bot@yandex.ru>
Merge-request: !10214
This commit is contained in:
Brad King 2025-01-30 13:47:37 +00:00 committed by Kitware Robot
commit 3e64c6a56e
51 changed files with 603 additions and 26 deletions

View File

@ -305,6 +305,7 @@ syn keyword cmakeProperty contained
\ MEASUREMENT
\ MODIFIED
\ MSVC_DEBUG_INFORMATION_FORMAT
\ MSVC_RUNTIME_CHECKS
\ MSVC_RUNTIME_LIBRARY
\ NAME
\ NO_SONAME
@ -1533,6 +1534,7 @@ syn keyword cmakeVariable contained
\ CMAKE_MODULE_PATH
\ CMAKE_MSVCIDE_RUN_PATH
\ CMAKE_MSVC_DEBUG_INFORMATION_FORMAT
\ CMAKE_MSVC_RUNTIME_CHECKS
\ CMAKE_MSVC_RUNTIME_LIBRARY
\ CMAKE_NETRC
\ CMAKE_NETRC_FILE

View File

@ -349,6 +349,7 @@ as needed to honor the state of the calling project:
* :policy:`CMP0155`
* :policy:`CMP0157`
* :policy:`CMP0181`
* :policy:`CMP0184`
.. versionadded:: 4.0
The current setting of :policy:`CMP0181` policy is propagated through to the
@ -417,6 +418,11 @@ configuration:
propagated into the test project's build configuration when using the
:ref:`whole-project signature <Try Compiling Whole Projects>`.
.. versionadded:: 4.0
If :policy:`CMP0184` is set to ``NEW``, one can use
:variable:`CMAKE_MSVC_RUNTIME_CHECKS` to specify the enabled MSVC runtime
checks.
See Also
^^^^^^^^

View File

@ -98,6 +98,7 @@ Policies Introduced by CMake 4.0
.. toctree::
:maxdepth: 1
CMP0184: MSVC runtime checks flags are selected by an abstraction. </policy/CMP0184>
CMP0183: add_feature_info() supports full Condition Syntax. </policy/CMP0183>
CMP0182: Create shared library archives by default on AIX. </policy/CMP0182>
CMP0181: Link command-line fragment variables are parsed and re-quoted. </policy/CMP0181>

View File

@ -359,6 +359,7 @@ Properties on Targets
/prop_tgt/MANUALLY_ADDED_DEPENDENCIES
/prop_tgt/MAP_IMPORTED_CONFIG_CONFIG
/prop_tgt/MSVC_DEBUG_INFORMATION_FORMAT
/prop_tgt/MSVC_RUNTIME_CHECKS
/prop_tgt/MSVC_RUNTIME_LIBRARY
/prop_tgt/NAME
/prop_tgt/NO_SONAME

View File

@ -519,6 +519,7 @@ Variables that Control the Build
/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG_INIT
/variable/CMAKE_MODULE_LINKER_FLAGS_INIT
/variable/CMAKE_MSVC_DEBUG_INFORMATION_FORMAT
/variable/CMAKE_MSVC_RUNTIME_CHECKS
/variable/CMAKE_MSVC_RUNTIME_LIBRARY
/variable/CMAKE_MSVCIDE_RUN_PATH
/variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX

View File

@ -13,8 +13,8 @@ In CMake 3.24 and below, debug information format flags are added to
the default :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>` cache entries by CMake
automatically. This allows users to edit their cache entries to adjust the
flags. However, the presence of such default flags is problematic for
projects that want to choose a different runtime library programmatically.
In particular, it requires string editing of the
projects that want to choose a different debug information format
programmatically. In particular, it requires string editing of the
:variable:`CMAKE_<LANG>_FLAGS_<CONFIG>` variables with knowledge of the
CMake builtin defaults so they can be replaced.

54
Help/policy/CMP0184.rst Normal file
View File

@ -0,0 +1,54 @@
CMP0184
-------
.. versionadded:: 4.0
MSVC runtime checks flags are selected by an abstraction.
Compilers targeting the MSVC ABI have flags to select the runtime checks.
Runtime checks selection typically varies with build
configuration.
In CMake 3.31 and below, runtime checks flags are added to
the default :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>` cache entries by CMake
automatically. This allows users to edit their cache entries to adjust the
flags. However, the presence of such default flags is problematic for
projects that want to choose different runtime checks programmatically.
In particular, it requires string editing of the
:variable:`CMAKE_<LANG>_FLAGS_<CONFIG>` variables with knowledge of the
CMake builtin defaults so they can be replaced.
CMake 4.0 and above prefer to leave the runtime checks flags
out of the default :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>` values and instead
offer a first-class abstraction. The
:variable:`CMAKE_MSVC_RUNTIME_CHECKS` variable and
:prop_tgt:`MSVC_RUNTIME_CHECKS` target property may be set to
select the MSVC runtime checks. If they are not set, CMake
enables runtime checks in ``Debug`` configuration using the default value
``$<$<CONFIG:Debug>:StackFrameErrorCheck;UninitializedVariable>``, if
supported by the compiler, or empty value otherwise.
This policy provides compatibility with projects that have not been updated
to be aware of the abstraction. The policy setting takes effect as of the
first :command:`project` or :command:`enable_language` command that enables
a language whose compiler targets the MSVC ABI.
.. note::
Once the policy has taken effect at the top of a project, that choice
will be used throughout the tree. In projects that have nested projects
in subdirectories, be sure to confirm if everything is working with the
selected policy behavior.
The ``OLD`` behavior for this policy is to place MSVC runtimes checks
flags in the default :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>` cache
entries and ignore the :variable:`CMAKE_MSVC_RUNTIME_CHECKS`
abstraction. The ``NEW`` behavior for this policy is to *not* place MSVC
runtime checks flags in the default cache entries and use
the abstraction instead.
.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 4.0
.. |WARNS_OR_DOES_NOT_WARN| replace:: does *not* warn
.. include:: STANDARD_ADVICE.txt
.. include:: DEPRECATED.txt

View File

@ -19,7 +19,7 @@ support per-configuration specification. For example, the code:
MSVC_DEBUG_INFORMATION_FORMAT "$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>")
selects for the target ``foo`` the program database debug information format
for the Debug configuration.
for the ``Debug`` and ``RelWithDebInfo`` configurations.
This property is initialized from the value of the
:variable:`CMAKE_MSVC_DEBUG_INFORMATION_FORMAT` variable, if it is set.

View File

@ -0,0 +1,16 @@
``PossibleDataLoss``
Compile with ``-RTCc`` or equivalent flag(s) to enable possible
data loss checks.
``StackFrameErrorCheck``
Compile with ``-RTCs`` or equivalent flag(s) to enable stack frame
error checks.
``UninitializedVariable``
Compile with ``-RTCu`` or equivalent flag(s) to enable uninitialized
variables checks.
The value is ignored on compilers not targeting the MSVC ABI, but an
unsupported value will be rejected as an error when using a compiler
targeting the MSVC ABI.
The value may also be the empty string (``""``), in which case no runtime
error check flags will be added explicitly by CMake.

View File

@ -0,0 +1,34 @@
MSVC_RUNTIME_CHECKS
-------------------
.. versionadded:: 4.0
Select the list of enabled runtime checks when targeting the MSVC ABI.
The allowed values are:
.. include:: MSVC_RUNTIME_CHECKS-VALUES.txt
Use :manual:`generator expressions <cmake-generator-expressions(7)>` to
support per-configuration specification. For example, the code:
.. code-block:: cmake
add_executable(foo foo.c)
set_property(TARGET foo PROPERTY
MSVC_RUNTIME_CHECKS "$<$<CONFIG:Debug,RelWithDebInfo>:PossibleDataLoss;UninitializedVariable>")
enables for the target ``foo`` the possible data loss and uninitialized variables checks
for the ``Debug`` and ``RelWithDebInfo`` configurations.
This property is initialized from the value of the
:variable:`CMAKE_MSVC_RUNTIME_CHECKS` variable, if it is set.
If this property is not set, CMake selects a runtime checks using
the default value ``$<$<CONFIG:Debug>:StackFrameErrorCheck;UninitializedVariable>``, if
supported by the compiler, or empty value otherwise.
.. note::
This property has effect only when policy :policy:`CMP0184` is set to ``NEW``
prior to the first :command:`project` or :command:`enable_language` command
that enables a language using a compiler targeting the MSVC ABI.

View File

@ -0,0 +1,7 @@
msvc-runtime-checks
-------------------
* The :variable:`CMAKE_MSVC_RUNTIME_CHECKS` variable and
:prop_tgt:`MSVC_RUNTIME_CHECKS` target property were introduced
to select runtime checks for compilers targeting the MSVC ABI.
See policy :policy:`CMP0184`.

View File

@ -21,7 +21,7 @@ support per-configuration specification. For example, the code:
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>")
selects for all following targets the program database debug information format
for the Debug configuration.
for the ``Debug`` and ``RelWithDebInfo`` configurations.
If this variable is not set, the :prop_tgt:`MSVC_DEBUG_INFORMATION_FORMAT`
target property will not be set automatically. If that property is not set,

View File

@ -0,0 +1,36 @@
CMAKE_MSVC_RUNTIME_CHECKS
-------------------------
.. versionadded:: 4.0
Select the list of enabled runtime checks when targeting the MSVC ABI.
This variable is used to initialize the
:prop_tgt:`MSVC_RUNTIME_CHECKS` property on all targets as they are
created. It is also propagated by calls to the :command:`try_compile` command
into the test project.
The allowed values are:
.. include:: ../prop_tgt/MSVC_RUNTIME_CHECKS-VALUES.txt
Use :manual:`generator expressions <cmake-generator-expressions(7)>` to
support per-configuration specification. For example, the code:
.. code-block:: cmake
set(CMAKE_MSVC_RUNTIME_CHECKS "$<$<CONFIG:Debug,RelWithDebInfo>:PossibleDataLoss;UninitializedVariable>")
enables for the target ``foo`` the possible data loss and uninitialized variables checks
for the ``Debug`` and ``RelWithDebInfo`` configurations.
If this variable is not set, the :prop_tgt:`MSVC_RUNTIME_CHECKS`
target property will not be set automatically. If that property is not set,
CMake selects runtime checks using the default value
``$<$<CONFIG:Debug>:StackFrameErrorCheck;UninitializedVariable>``,
if supported by the compiler, or empty value otherwise.
.. note::
This variable has effect only when policy :policy:`CMP0184` is set to ``NEW``
prior to the first :command:`project` or :command:`enable_language` command
that enables a language using a compiler targeting the MSVC ABI.

View File

@ -11,12 +11,15 @@ set(CMAKE_ASM${ASM_DIALECT}_SOURCE_FILE_EXTENSIONS asm)
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <INCLUDES> <FLAGS> -o <OBJECT> <SOURCE>")
set(CMAKE_ASM${ASM_DIALECT}_CREATE_STATIC_LIBRARY "<CMAKE_AR> <LINK_FLAGS> /out:<TARGET> <OBJECTS> ")
# The ASM_MARMASM compiler id for this compiler is "MSVC", so fill out the runtime library table.
# The ASM_MARMASM compiler id for this compiler is "MSVC", so fill out the abstraction tables.
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_PossibleDataLoss "")
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_StackFrameErrorCheck "")
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_UninitializedVariable "")
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_RTCsu "")
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded "")
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL "")
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug "")
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL "")
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_Embedded "-g")
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_ProgramDatabase "")
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_EditAndContinue "")

View File

@ -11,12 +11,15 @@ set(CMAKE_ASM${ASM_DIALECT}_SOURCE_FILE_EXTENSIONS asm)
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -c -Fo <OBJECT> <SOURCE>")
set(CMAKE_ASM${ASM_DIALECT}_CREATE_STATIC_LIBRARY "<CMAKE_AR> <LINK_FLAGS> /out:<TARGET> <OBJECTS> ")
# The ASM_MASM compiler id for this compiler is "MSVC", so fill out the runtime library table.
# The ASM_MASM compiler id for this compiler is "MSVC", so fill out the abstraction tables.
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_PossibleDataLoss "")
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_StackFrameErrorCheck "")
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_UninitializedVariable "")
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_RTCsu "")
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded "")
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL "")
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug "")
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL "")
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_Embedded "-Zi")
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_ProgramDatabase "")
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_EditAndContinue "")

View File

@ -1,6 +1,10 @@
include(Platform/Windows-Clang)
__windows_compiler_clang(ASM)
set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_PossibleDataLoss "")
set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_StackFrameErrorCheck "")
set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_UninitializedVariable "")
set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_RTCsu "")
set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded "")
set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL "")
set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug "")

View File

@ -117,6 +117,13 @@ macro(__windows_compiler_clang_gnu lang)
string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -O3 -DNDEBUG${_RTL_FLAGS}")
string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -O2 -DNDEBUG${_DBG_FLAGS}${_RTL_FLAGS}")
# clang-cl accepts -RTC* flags but ignores them. Simulate this
# with the GNU-like drivers by simply passing no flags at all.
set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_PossibleDataLoss "")
set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_StackFrameErrorCheck "")
set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_UninitializedVariable "")
set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_RTCsu "")
set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_Embedded -g -Xclang -gcodeview)
#set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_ProgramDatabase) # not supported by Clang
#set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_EditAndContinue) # not supported by Clang
@ -239,6 +246,14 @@ endmacro()
endif()
unset(__WINDOWS_MSVC_CMP0141)
cmake_policy(GET CMP0184 __WINDOWS_MSVC_CMP0184)
if(__WINDOWS_MSVC_CMP0184 STREQUAL "NEW")
set(CMAKE_MSVC_RUNTIME_CHECKS_DEFAULT "$<$<CONFIG:Debug>:StackFrameErrorCheck;UninitializedVariable>")
else()
set(CMAKE_MSVC_RUNTIME_CHECKS_DEFAULT "")
endif()
unset(__WINDOWS_MSVC_CMP0184)
set(CMAKE_BUILD_TYPE_INIT Debug)
__enable_llvm_rc_preprocessing("" "-x c")

View File

@ -29,6 +29,12 @@ unset(_LIBSDLL)
unset(_DBGLIBS)
unset(_THREADS)
# icl accepts -RTC* flags but ignores them. ifort accepts -RTCu only.
set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_PossibleDataLoss "")
set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_StackFrameErrorCheck "")
set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_UninitializedVariable -RTCu)
set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_RTCsu "")
set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded -threads -libs:static)
set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL -threads -libs:dll)
set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug -threads -libs:static -dbglibs)

View File

@ -29,6 +29,12 @@ unset(_LIBSDLL)
unset(_DBGLIBS)
unset(_THREADS)
# icx accepts -RTC* flags but ignores them. ifx accepts -RTCu only.
set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_PossibleDataLoss "")
set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_StackFrameErrorCheck "")
set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_UninitializedVariable -RTCu)
set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_RTCsu "")
set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded -threads -libs:static)
set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL -threads -libs:dll)
set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug -threads -libs:static -dbglibs)

View File

@ -192,6 +192,9 @@ if(WINCE)
set(_PLATFORM_DEFINES_CXX " /D${_MSVC_CXX_ARCHITECTURE_FAMILY} /D_${_MSVC_CXX_ARCHITECTURE_FAMILY_UPPER}_")
set(_RTC1 "")
set(_RTCc "")
set(_RTCs "")
set(_RTCu "")
set(_FLAGS_C "")
set(_FLAGS_CXX "${_GR} /EHsc")
@ -248,17 +251,24 @@ else()
if(CMAKE_VS_PLATFORM_TOOLSET MATCHES "v[0-9]+_clang_.*")
# Clang/C2 in MSVC14 Update 1 seems to not support -fsantinize (yet?)
# set(_RTC1 "-fsantinize=memory,safe-stack")
# set(_RTCs "-fsantinize=safe-stack")
# set(_RTCu "-fsantinize=memory")
set(_FLAGS_CXX " -frtti -fexceptions")
else()
set(_RTC1 "/RTC1")
set(_RTC1 "-RTC1")
set(_RTCc "-RTCc")
set(_RTCs "-RTCs")
set(_RTCu "-RTCu")
set(_FLAGS_CXX "${_GR} /EHsc")
endif()
set(CMAKE_C_STANDARD_LIBRARIES_INIT "kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib")
else()
set(_RTC1 "/GZ")
set(_RTC1 "-GZ")
set(_RTCs "-GZ")
set(_FLAGS_CXX "${_GR} /GX")
set(CMAKE_C_STANDARD_LIBRARIES_INIT "kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib")
endif()
set(_RTCsu "${_RTC1}")
if((_MSVC_C_ARCHITECTURE_FAMILY STREQUAL "ARM64EC") OR (_MSVC_CXX_ARCHITECTURE_FAMILY STREQUAL "ARM64EC"))
string(APPEND CMAKE_C_STANDARD_LIBRARIES_INIT " softintrin.lib")
@ -353,6 +363,13 @@ else()
endif()
unset(__WINDOWS_MSVC_CMP0141)
cmake_policy(GET CMP0184 __WINDOWS_MSVC_CMP0184)
if(__WINDOWS_MSVC_CMP0184 STREQUAL "NEW")
set(CMAKE_MSVC_RUNTIME_CHECKS_DEFAULT "$<$<CONFIG:Debug>:StackFrameErrorCheck;UninitializedVariable>")
else()
set(CMAKE_MSVC_RUNTIME_CHECKS_DEFAULT "")
endif()
unset(__WINDOWS_MSVC_CMP0184)
macro(__windows_compiler_msvc lang)
if(NOT MSVC_VERSION LESS 1400)
@ -467,17 +484,23 @@ macro(__windows_compiler_msvc lang)
set(_Zi " /Zi")
endif()
if(CMAKE_MSVC_RUNTIME_CHECKS_DEFAULT)
set(_RTC1_local "")
else()
string(REPLACE " -" " /" _RTC1_local " ${_RTC1}")
endif()
if(CMAKE_VS_PLATFORM_TOOLSET MATCHES "v[0-9]+_clang_.*")
# note: MSVC 14 2015 Update 1 sets -fno-ms-compatibility by default, but this does not allow one to compile many projects
# that include MS's own headers. CMake itself is affected project too.
string(APPEND CMAKE_${lang}_FLAGS_INIT " ${_PLATFORM_DEFINES}${_PLATFORM_DEFINES_${lang}} -fms-extensions -fms-compatibility -D_WINDOWS${_Wall}${_FLAGS_${lang}}")
string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT "${_MDd} -gline-tables-only -fno-inline -O0 ${_RTC1}")
string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT "${_MDd} -gline-tables-only -fno-inline -O0${_RTC1_local}")
string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT "${_MD} -O2 -DNDEBUG")
string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "${_MD} -gline-tables-only -O2 -fno-inline -DNDEBUG")
string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "${_MD} -DNDEBUG") # TODO: Add '-Os' once VS generator maps it properly for Clang
else()
string(APPEND CMAKE_${lang}_FLAGS_INIT " ${_PLATFORM_DEFINES}${_PLATFORM_DEFINES_${lang}} /D_WINDOWS${_W3}${_FLAGS_${lang}}")
string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT "${_MDd}${_Zi} /Ob0 /Od ${_RTC1}")
string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT "${_MDd}${_Zi} /Ob0 /Od${_RTC1_local}")
string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT "${_MD} /O2 /Ob2 /DNDEBUG")
string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "${_MD}${_Zi} /O2 /Ob1 /DNDEBUG")
string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "${_MD} /O1 /Ob1 /DNDEBUG")
@ -487,7 +510,12 @@ macro(__windows_compiler_msvc lang)
unset(_MDd)
unset(_MD)
unset(_Zi)
unset(_RTC1_local)
set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_PossibleDataLoss "${_RTCc}")
set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_StackFrameErrorCheck "${_RTCs}")
set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_UninitializedVariable "${_RTCu}")
set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_RTCsu "${_RTCsu}")
set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded -MT)
set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL -MD)
set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug -MTd)

View File

@ -68,6 +68,12 @@ else()
set(_Zi " -Zi")
endif()
if(CMAKE_MSVC_RUNTIME_CHECKS_DEFAULT)
set(_RTC1_local "")
else()
string(REPLACE " -" " /" _RTC1_local " ${_RTC1}")
endif()
cmake_policy(GET CMP0092 _cmp0092)
if(_cmp0092 STREQUAL "NEW")
set(_W3 "")
@ -77,7 +83,7 @@ endif()
unset(_cmp0092)
string(APPEND CMAKE_CUDA_FLAGS_INIT " ${PLATFORM_DEFINES_CUDA} -D_WINDOWS -Xcompiler=\"${_W3}${_FLAGS_CXX}\"")
string(APPEND CMAKE_CUDA_FLAGS_DEBUG_INIT " -Xcompiler=\"${_MDd}${_Zi} -Ob0 -Od ${_RTC1}\"")
string(APPEND CMAKE_CUDA_FLAGS_DEBUG_INIT " -Xcompiler=\"${_MDd}${_Zi} -Ob0 -Od${_RTC1_local}\"")
string(APPEND CMAKE_CUDA_FLAGS_RELEASE_INIT " -Xcompiler=\"${_MD}-O2 -Ob2\" -DNDEBUG")
string(APPEND CMAKE_CUDA_FLAGS_RELWITHDEBINFO_INIT " -Xcompiler=\"${_MD}${_Zi} -O2 -Ob1\" -DNDEBUG")
string(APPEND CMAKE_CUDA_FLAGS_MINSIZEREL_INIT " -Xcompiler=\"${_MD}-O1 -Ob1\" -DNDEBUG")
@ -85,7 +91,12 @@ unset(_W3)
unset(_Zi)
unset(_MDd)
unset(_MD)
unset(_RTC1_local)
set(CMAKE_CUDA_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_PossibleDataLoss "-Xcompiler=${_RTCc} -D_ALLOW_RTCc_IN_STL")
set(CMAKE_CUDA_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_StackFrameErrorCheck "-Xcompiler=${_RTCs}")
set(CMAKE_CUDA_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_UninitializedVariable "-Xcompiler=${_RTCu}")
set(CMAKE_CUDA_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_RTCsu "-Xcompiler=${_RTCsu}")
set(CMAKE_CUDA_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded -Xcompiler=-MT)
set(CMAKE_CUDA_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL -Xcompiler=-MD)
set(CMAKE_CUDA_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug -Xcompiler=-MTd)

View File

@ -110,6 +110,8 @@ std::string const kCMAKE_WATCOM_RUNTIME_LIBRARY_DEFAULT =
"CMAKE_WATCOM_RUNTIME_LIBRARY_DEFAULT";
std::string const kCMAKE_MSVC_DEBUG_INFORMATION_FORMAT_DEFAULT =
"CMAKE_MSVC_DEBUG_INFORMATION_FORMAT_DEFAULT";
std::string const kCMAKE_MSVC_RUNTIME_CHECKS_DEFAULT =
"CMAKE_MSVC_RUNTIME_CHECKS_DEFAULT";
/* GHS Multi platform variables */
std::set<std::string> const ghs_platform_vars{
@ -683,6 +685,13 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
!msvcDebugInformationFormatDefault->empty() ? "NEW" : "OLD");
}
/* Set MSVC runtime checks policy to match our selection. */
if (cmValue msvcRuntimeChecksDefault =
this->Makefile->GetDefinition(kCMAKE_MSVC_RUNTIME_CHECKS_DEFAULT)) {
fprintf(fout, "cmake_policy(SET CMP0184 %s)\n",
!msvcRuntimeChecksDefault->empty() ? "NEW" : "OLD");
}
/* Set cache/normal variable policy to match outer project.
It may affect toolchain files. */
if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0126) !=
@ -1111,6 +1120,7 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
vars.emplace("CMAKE_MSVC_RUNTIME_LIBRARY"_s);
vars.emplace("CMAKE_WATCOM_RUNTIME_LIBRARY"_s);
vars.emplace("CMAKE_MSVC_DEBUG_INFORMATION_FORMAT"_s);
vars.emplace("CMAKE_MSVC_RUNTIME_CHECKS"_s);
vars.emplace("CMAKE_CXX_COMPILER_CLANG_SCAN_DEPS"_s);
vars.emplace("CMAKE_VS_USE_DEBUG_LIBRARIES"_s);

View File

@ -2193,10 +2193,7 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
"CMAKE_" + lang + "_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_" +
msvcRuntimeLibrary)) {
this->AppendCompileOptions(flags, *msvcRuntimeLibraryOptions);
} else if ((this->Makefile->GetSafeDefinition(
"CMAKE_" + lang + "_COMPILER_ID") == "MSVC" ||
this->Makefile->GetSafeDefinition(
"CMAKE_" + lang + "_SIMULATE_ID") == "MSVC") &&
} else if ((compiler == "MSVC" || compilerSimulateId == "MSVC") &&
!cmSystemTools::GetErrorOccurredFlag()) {
// The compiler uses the MSVC ABI so it needs a known runtime library.
this->IssueMessage(MessageType::FATAL_ERROR,
@ -2224,10 +2221,8 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
"CMAKE_" + lang + "_COMPILE_OPTIONS_WATCOM_RUNTIME_LIBRARY_" +
watcomRuntimeLibrary)) {
this->AppendCompileOptions(flags, *watcomRuntimeLibraryOptions);
} else if ((this->Makefile->GetSafeDefinition(
"CMAKE_" + lang + "_COMPILER_ID") == "OpenWatcom" ||
this->Makefile->GetSafeDefinition(
"CMAKE_" + lang + "_SIMULATE_ID") == "OpenWatcom") &&
} else if ((compiler == "OpenWatcom" ||
compilerSimulateId == "OpenWatcom") &&
!cmSystemTools::GetErrorOccurredFlag()) {
// The compiler uses the Watcom ABI so it needs a known runtime
// library.
@ -2239,6 +2234,49 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
}
}
// Add MSVC runtime checks flags. This is activated by the presence
// of a default selection whether or not it is overridden by a property.
cmValue msvcRuntimeChecksDefault =
this->Makefile->GetDefinition("CMAKE_MSVC_RUNTIME_CHECKS_DEFAULT");
if (cmNonempty(msvcRuntimeChecksDefault)) {
cmValue msvcRuntimeChecksValue =
target->GetProperty("MSVC_RUNTIME_CHECKS");
if (!msvcRuntimeChecksValue) {
msvcRuntimeChecksValue = msvcRuntimeChecksDefault;
}
cmList msvcRuntimeChecksList = cmGeneratorExpression::Evaluate(
*msvcRuntimeChecksValue, this, config, target);
msvcRuntimeChecksList.remove_duplicates();
// RTC1/RTCsu VS GUI workaround
std::string const stackFrameErrorCheck = "StackFrameErrorCheck";
std::string const unitinitializedVariable = "UninitializedVariable";
std::string const rtcSU = "RTCsu";
if ((cm::contains(msvcRuntimeChecksList, stackFrameErrorCheck) &&
cm::contains(msvcRuntimeChecksList, unitinitializedVariable)) ||
cm::contains(msvcRuntimeChecksList, rtcSU)) {
msvcRuntimeChecksList.remove_items(
{ stackFrameErrorCheck, unitinitializedVariable, rtcSU });
msvcRuntimeChecksList.append(rtcSU);
}
for (std::string const& msvcRuntimeChecks : msvcRuntimeChecksList) {
if (cmValue msvcRuntimeChecksOptions =
this->Makefile->GetDefinition(cmStrCat(
"CMAKE_", lang,
"_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_" + msvcRuntimeChecks))) {
this->AppendCompileOptions(flags, *msvcRuntimeChecksOptions);
} else if ((compiler == "MSVC" || compilerSimulateId == "MSVC") &&
!cmSystemTools::GetErrorOccurredFlag()) {
// The compiler uses the MSVC ABI so it needs a known runtime checks.
this->IssueMessage(MessageType::FATAL_ERROR,
cmStrCat("MSVC_RUNTIME_CHECKS value '",
msvcRuntimeChecks, "' not known for this ",
lang, " compiler."));
}
}
}
// Add MSVC debug information format flags if CMP0141 is NEW.
if (cm::optional<std::string> msvcDebugInformationFormat =
this->GetMSVCDebugFormatName(config, target)) {
@ -2249,10 +2287,7 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
"_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_",
*msvcDebugInformationFormat))) {
this->AppendCompileOptions(flags, *msvcDebugInformationFormatOptions);
} else if ((this->Makefile->GetSafeDefinition(
cmStrCat("CMAKE_", lang, "_COMPILER_ID")) == "MSVC"_s ||
this->Makefile->GetSafeDefinition(
cmStrCat("CMAKE_", lang, "_SIMULATE_ID")) == "MSVC"_s) &&
} else if ((compiler == "MSVC" || compilerSimulateId == "MSVC") &&
!cmSystemTools::GetErrorOccurredFlag()) {
// The compiler uses the MSVC ABI so it needs a known runtime library.
this->IssueMessage(MessageType::FATAL_ERROR,

View File

@ -549,7 +549,10 @@ class cmMakefile;
SELECT(POLICY, CMP0182, \
"Create shared library archives by default on AIX.", 4, 0, 0, WARN) \
SELECT(POLICY, CMP0183, \
"add_feature_info() supports full Condition Syntax.", 4, 0, 0, WARN)
"add_feature_info() supports full Condition Syntax.", 4, 0, 0, WARN) \
SELECT(POLICY, CMP0184, \
"MSVC runtime check flags are selected by an abstraction.", 4, 0, 0, \
WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \

View File

@ -330,6 +330,7 @@ TargetProperty const StaticTargetProperties[] = {
{ "OSX_ARCHITECTURES"_s, IC::CanCompileSources },
// ---- Windows
{ "MSVC_DEBUG_INFORMATION_FORMAT"_s, IC::CanCompileSources },
{ "MSVC_RUNTIME_CHECKS"_s, IC::CanCompileSources },
{ "MSVC_RUNTIME_LIBRARY"_s, IC::CanCompileSources },
{ "VS_JUST_MY_CODE_DEBUGGING"_s, IC::CanCompileSources },
{ "VS_DEBUGGER_COMMAND"_s, IC::ExecutableTarget },
@ -1763,6 +1764,7 @@ void cmTarget::CopyImportedCxxModulesProperties(cmTarget const* tgt)
"OSX_ARCHITECTURES",
// ---- Windows
"MSVC_DEBUG_INFORMATION_FORMAT",
"MSVC_RUNTIME_CHECKS",
"MSVC_RUNTIME_LIBRARY",
"VS_PLATFORM_TOOLSET",
// ---- OpenWatcom

View File

@ -2128,6 +2128,14 @@ if(BUILD_TESTING)
set_property(TEST MSVCDebugInformationFormat APPEND
PROPERTY LABELS "CUDA" "Fortran")
set(MSVCRuntimeChecks_BUILD_OPTIONS -DCMake_TEST_CUDA=${CMake_TEST_CUDA})
if(CMAKE_Fortran_COMPILER)
list(APPEND MSVCRuntimeChecks_BUILD_OPTIONS -DCMake_TEST_Fortran=1)
endif()
ADD_TEST_MACRO(MSVCRuntimeChecks)
set_property(TEST MSVCRuntimeChecks APPEND
PROPERTY LABELS "CUDA" "Fortran")
set(MSVCRuntimeLibrary_BUILD_OPTIONS -DCMake_TEST_CUDA=${CMake_TEST_CUDA})
ADD_TEST_MACRO(MSVCRuntimeLibrary)
set_property(TEST MSVCRuntimeLibrary APPEND

View File

@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 3.10...3.25) # Enable CMP0091 and CMP0141.
cmake_policy(SET CMP0184 NEW)
project(FortranOnly Fortran)
message("CTEST_FULL_OUTPUT ")

View File

@ -0,0 +1,105 @@
cmake_minimum_required(VERSION 3.31)
cmake_policy(SET CMP0184 NEW)
# All runtime checks flags enables single preprocessor definition,
# so override our table of flags to artificially add a definition we can check.
set(CMAKE_USER_MAKE_RULES_OVERRIDE_C ${CMAKE_CURRENT_SOURCE_DIR}/override-C.cmake)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX ${CMAKE_CURRENT_SOURCE_DIR}/override-CXX.cmake)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_CUDA ${CMAKE_CURRENT_SOURCE_DIR}/override-CUDA.cmake)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_Fortran ${CMAKE_CURRENT_SOURCE_DIR}/override-Fortran.cmake)
project(MSVCRuntimeChecks)
if(CMake_TEST_CUDA STREQUAL "NVIDIA")
enable_language(CUDA)
endif()
if(CMake_TEST_Fortran)
enable_language(Fortran)
endif()
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
set(verify_default VERIFY_RTCsu)
set(verify_def_PossibleDataLoss -DVERIFY_RTCc)
set(verify_def_StackFrameErrorCheck -DVERIFY_RTCs)
set(verify_def_UninitializedVariable -DVERIFY_RTCu)
set(verify_def_RTCsu -DVERIFY_RTCsu)
function(verify_combination format verify_format_defs lang src)
# Test that try_compile builds with this runtime check.
set(CMAKE_MSVC_RUNTIME_CHECKS "${format}")
set(CMAKE_TRY_COMPILE_CONFIGURATION "Debug")
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
string(REPLACE ";" "_" format_var_name "${format}")
if (NOT format_var_name)
set(format_var_name "Empty")
endif()
if (NOT verify_format_defs)
foreach(format_for_def IN LISTS format)
list(APPEND verify_format_defs ${verify_def_${format_for_def}})
endforeach()
endif()
try_compile(${format_var_name}_COMPILES
${CMAKE_CURRENT_BINARY_DIR}/try_compile/${format_var_name}
${CMAKE_CURRENT_SOURCE_DIR}/${src}
COMPILE_DEFINITIONS ${verify_format_defs}
CMAKE_FLAGS -DINCLUDE_DIRECTORIES=${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE ${format_var_name}_OUTPUT
)
if(${format_var_name}_COMPILES)
message(STATUS "try_compile ${lang} with \"${format}\" worked")
else()
string(REPLACE "\n" "\n " ${format_var_name}_OUTPUT " ${${format_var_name}_OUTPUT}")
message(SEND_ERROR "try_compile ${lang} with \"${format}\" failed:\n${${format_var_name}_OUTPUT}")
endif()
# Test that targets build with this runtime check.
set(CMAKE_MSVC_RUNTIME_CHECKS "$<$<BOOL:$<TARGET_PROPERTY:BOOL_TRUE>>:${format}>$<$<BOOL:$<TARGET_PROPERTY:BOOL_FALSE>>:BadContent>")
add_library(${format_var_name}-${lang} ${src})
set_property(TARGET ${format_var_name}-${lang} PROPERTY BOOL_TRUE TRUE)
target_compile_definitions(${format_var_name}-${lang} PRIVATE ${verify_format_defs})
endfunction()
function(verify lang src)
add_library(default-${lang} ${src})
target_compile_definitions(default-${lang} PRIVATE "$<$<CONFIG:Debug>:${verify_default}>")
# zero checkers
verify_combination("" "" ${lang} ${src})
# single checker
verify_combination(PossibleDataLoss "" ${lang} ${src})
verify_combination(StackFrameErrorCheck "" ${lang} ${src})
verify_combination(UninitializedVariable "" ${lang} ${src})
verify_combination(RTCsu "" ${lang} ${src})
# multiple checkers (without RTCsu merging)
verify_combination("PossibleDataLoss;StackFrameErrorCheck" "" ${lang} ${src})
verify_combination("PossibleDataLoss;UninitializedVariable" "" ${lang} ${src})
# multiple checkers (only RTCsu merging)
set(defs "${verify_def_RTCsu}")
verify_combination("StackFrameErrorCheck;UninitializedVariable" "${defs}" ${lang} ${src})
verify_combination("StackFrameErrorCheck;RTCsu" "${defs}" ${lang} ${src})
verify_combination("UninitializedVariable;RTCsu" "${defs}" ${lang} ${src})
verify_combination("StackFrameErrorCheck;UninitializedVariable;RTCsu" "${defs}" ${lang} ${src})
# multiple checkers (with RTCsu merging)
list(APPEND defs "${verify_def_PossibleDataLoss}")
verify_combination("PossibleDataLoss;StackFrameErrorCheck;UninitializedVariable" "${defs}" ${lang} ${src})
verify_combination("PossibleDataLoss;StackFrameErrorCheck;RTCsu" "${defs}" ${lang} ${src})
verify_combination("PossibleDataLoss;UninitializedVariable;RTCsu" "${defs}" ${lang} ${src})
verify_combination("PossibleDataLoss;StackFrameErrorCheck;UninitializedVariable;RTCsu" "${defs}" ${lang} ${src})
endfunction()
verify(C verify.c)
verify(CXX verify.cxx)
if(CMake_TEST_CUDA STREQUAL "NVIDIA")
verify(CUDA verify.cu)
endif()
if(CMake_TEST_Fortran)
verify(Fortran verify.F90)
endif()

View File

@ -0,0 +1,3 @@
set(delimiter ";")
set(lang "C")
include(${CMAKE_CURRENT_LIST_DIR}/override-common.cmake)

View File

@ -0,0 +1,3 @@
set(delimiter " ")
set(lang "CUDA")
include(${CMAKE_CURRENT_LIST_DIR}/override-common.cmake)

View File

@ -0,0 +1,3 @@
set(delimiter ";")
set(lang "CXX")
include(${CMAKE_CURRENT_LIST_DIR}/override-common.cmake)

View File

@ -0,0 +1,3 @@
set(delimiter ";")
set(lang "Fortran")
include(${CMAKE_CURRENT_LIST_DIR}/override-common.cmake)

View File

@ -0,0 +1,50 @@
if("${CMAKE_${lang}_COMPILER_ID};${CMAKE_${lang}_SIMULATE_ID};${CMAKE_${lang}_COMPILER_FRONTEND_VARIANT}" STREQUAL "Clang;MSVC;GNU")
# Clang does not actually support these, so Windows-Clang passes no flags.
set(empty_PossibleDataLoss 1)
set(empty_StackFrameErrorCheck 1)
set(empty_UninitializedVariable 1)
set(empty_RTCsu 1)
elseif("${CMAKE_${lang}_COMPILER_ID};${CMAKE_${lang}_SIMULATE_ID};${lang}" MATCHES "^Intel(LLVM)?;MSVC;Fortran$")
# IntelLLVM Fortran does not actually support these, so Windows-IntelLLVM-Fortran passes no flags.
set(empty_PossibleDataLoss 1)
set(empty_StackFrameErrorCheck 1)
set(empty_UninitializedVariable 0) # this one is supported
set(empty_RTCsu 1)
elseif(CMAKE_${lang}_COMPILER_ID STREQUAL "MSVC" AND CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 14)
set(empty_PossibleDataLoss 1)
set(empty_StackFrameErrorCheck 0)
set(empty_UninitializedVariable 1)
set(empty_RTCsu 0)
else()
set(empty_PossibleDataLoss 0)
set(empty_StackFrameErrorCheck 0)
set(empty_UninitializedVariable 0)
set(empty_RTCsu 0)
endif()
set(var "CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_PossibleDataLoss")
if(empty_PossibleDataLoss AND ${var} STREQUAL "")
set("${var}" "-DTEST_RTCc")
else()
string(REPLACE "-RTCc" "-RTCc${delimiter}-DTEST_RTCc" "${var}" "${${var}}")
endif()
set(var "CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_StackFrameErrorCheck")
if(empty_StackFrameErrorCheck AND ${var} STREQUAL "")
set("${var}" "-DTEST_RTCs")
else()
string(REPLACE "-RTCs" "-RTCs${delimiter}-DTEST_RTCs" "${var}" "${${var}}")
string(REPLACE "-GZ" "-GZ${delimiter}-DTEST_RTCs" "${var}" "${${var}}")
endif()
set(var "CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_UninitializedVariable")
if(empty_UninitializedVariable AND ${var} STREQUAL "")
set("${var}" "-DTEST_RTCu")
else()
string(REPLACE "-RTCu" "-RTCu${delimiter}-DTEST_RTCu" "${var}" "${${var}}")
endif()
set(var "CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_CHECKS_RTCsu")
if(empty_RTCsu AND ${var} STREQUAL "")
set("${var}" "-DTEST_RTCsu")
else()
string(REPLACE "-RTC1" "-RTC1${delimiter}-DTEST_RTCsu" "${var}" "${${var}}")
string(REPLACE "-GZ" "-GZ${delimiter}-DTEST_RTCsu" "${var}" "${${var}}")
endif()

View File

@ -0,0 +1 @@
#include "verify.h"

View File

@ -0,0 +1 @@
#include "verify.h"

View File

@ -0,0 +1 @@
#include "verify.h"

View File

@ -0,0 +1 @@
#include "verify.h"

View File

@ -0,0 +1,61 @@
/* Some compilers ignore the -RTC flags even if specified. */
#if (defined(_MSC_VER) && _MSC_VER <= 1310) || defined(__clang__) || \
defined(__INTEL_LLVM_COMPILER) || defined(__INTEL_COMPILER)
# define NO__MSVC_RUNTIME_CHECKS
#endif
#ifdef VERIFY_RTCc
# ifndef TEST_RTCc
# error "TEST_RTCc incorrectly not defined by enabled runtime check"
# endif
# if !defined(__MSVC_RUNTIME_CHECKS) && !defined(NO__MSVC_RUNTIME_CHECKS)
# error \
"__MSVC_RUNTIME_CHECKS incorrectly not defined by enabled RTCc runtime check"
# endif
#else
# ifdef TEST_RTCc
# error "TEST_RTCc incorrectly defined by disabled runtime check"
# endif
#endif
#ifdef VERIFY_RTCs
# ifndef TEST_RTCs
# error "TEST_RTCs incorrectly not defined by enabled runtime check"
# endif
# if !defined(__MSVC_RUNTIME_CHECKS) && !defined(NO__MSVC_RUNTIME_CHECKS)
# error \
"__MSVC_RUNTIME_CHECKS incorrectly not defined by enabled RTCs runtime check"
# endif
#else
# ifdef TEST_RTCs
# error "TEST_RTCs incorrectly defined by disabled runtime check"
# endif
#endif
#ifdef VERIFY_RTCu
# ifndef TEST_RTCu
# error "TEST_RTCu incorrectly not defined by enabled runtime check"
# endif
# if !defined(__MSVC_RUNTIME_CHECKS) && !defined(NO__MSVC_RUNTIME_CHECKS)
# error \
"__MSVC_RUNTIME_CHECKS incorrectly not defined by enabled RTCu runtime check"
# endif
#else
# ifdef TEST_RTCu
# error "TEST_RTCu incorrectly defined by disabled runtime check"
# endif
#endif
#ifdef VERIFY_RTCsu
# ifndef TEST_RTCsu
# error "TEST_RTCsu incorrectly not defined by enabled runtime check"
# endif
# if !defined(__MSVC_RUNTIME_CHECKS) && !defined(NO__MSVC_RUNTIME_CHECKS)
# error \
"__MSVC_RUNTIME_CHECKS incorrectly not defined by enabled RTCsu runtime check"
# endif
#else
# ifdef TEST_RTCsu
# error "TEST_RTCsu incorrectly defined by disabled runtime check"
# endif
#endif

View File

@ -483,6 +483,7 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "^(Cray|PGI|NVHPC|XL|XLClang|IBMClang|Fujitsu|F
add_RunCMake_test(MetaCompileFeatures)
endif()
if(MSVC)
add_RunCMake_test(MSVCRuntimeChecks)
add_RunCMake_test(MSVCRuntimeLibrary)
add_RunCMake_test(MSVCRuntimeTypeInfo)
add_RunCMake_test(MSVCWarningFlags)

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,4 @@
^CMake Error in CMakeLists.txt:
MSVC_RUNTIME_CHECKS value 'BogusValue' not known for this C compiler.
+
CMake Generate step failed\. Build files cannot be regenerated correctly\.$

View File

@ -0,0 +1,2 @@
cmake_policy(SET CMP0184 NEW)
include(CMP0184-common.cmake)

View File

@ -0,0 +1,4 @@
include(CMP0184-common.cmake)
# Setting this policy after enable_language command has no effect.
cmake_policy(SET CMP0184 NEW)

View File

@ -0,0 +1,2 @@
cmake_policy(SET CMP0184 OLD)
include(CMP0184-common.cmake)

View File

@ -0,0 +1,2 @@
include(CMP0184-common.cmake)

View File

@ -0,0 +1,25 @@
enable_language(C)
cmake_policy(GET CMP0184 cmp0184)
if(cmp0184 STREQUAL "NEW")
if(NOT CMAKE_MSVC_RUNTIME_CHECKS_DEFAULT)
message(SEND_ERROR "CMAKE_MSVC_RUNTIME_CHECKS_DEFAULT not set under NEW behavior")
endif()
else()
if(CMAKE_MSVC_RUNTIME_CHECKS_DEFAULT)
message(SEND_ERROR "CMAKE_MSVC_RUNTIME_CHECKS_DEFAULT is set under OLD behavior")
endif()
endif()
if(cmp0184 STREQUAL "NEW")
if(CMAKE_C_FLAGS_DEBUG MATCHES "[/-](RTC1|GZ)( |$)")
message(SEND_ERROR "CMAKE_C_FLAGS_DEBUG has -RTC1 flag under NEW behavior:\n ${CMAKE_C_FLAGS_DEBUG}")
endif()
else()
if(NOT (CMAKE_C_FLAGS_DEBUG MATCHES "/(RTC1|GZ)( |$)"))
message(SEND_ERROR "CMAKE_C_FLAGS_DEBUG does not have /RTC1 flag under OLD behavior:\n ${CMAKE_C_FLAGS_DEBUG}")
endif()
endif()
set(CMAKE_MSVC_RUNTIME_CHECKS BogusValue)
add_library(foo empty.c)

View File

@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 3.31)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)

View File

@ -0,0 +1,6 @@
include(RunCMake)
run_cmake(CMP0184-WARN)
run_cmake(CMP0184-OLD)
run_cmake(CMP0184-NEW)
run_cmake(CMP0184-NoEffect)

View File

View File

@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 3.25) # Enable CMP0141
cmake_policy(SET CMP0184 NEW)
project(VSMARMASM C ASM_MARMASM)
add_executable(VSMARMASM main.c foo.asm)
target_compile_options(VSMARMASM PRIVATE

View File

@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 3.25) # Enable CMP0141
cmake_policy(SET CMP0184 NEW)
project(VSMASM C ASM_MASM)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
add_definitions(-DTESTx64)