summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Copyright.txt1
-rw-r--r--Help/command/add_custom_command.rst7
-rw-r--r--Help/envvar/CUDAARCHS.rst3
-rw-r--r--Help/envvar/CUDAHOSTCXX.rst5
-rw-r--r--Help/manual/cmake-variables.7.rst4
-rw-r--r--Help/prop_tgt/LANG_STANDARD.rst7
-rw-r--r--Help/prop_tgt/LANG_STANDARD_REQUIRED.rst16
-rw-r--r--Help/variable/CMAKE_LANG_LINKER_PREFERENCE.rst2
-rw-r--r--Help/variable/CMAKE_LANG_LINKER_PREFERENCE_PROPAGATES.rst2
-rw-r--r--Modules/CMakeDetermineCUDACompiler.cmake18
-rw-r--r--Modules/CheckLinkerFlag.cmake49
-rw-r--r--Modules/Internal/CheckCompilerFlag.cmake68
-rw-r--r--Modules/Internal/CheckFlagCommonConfig.cmake75
-rw-r--r--Modules/Internal/CheckLinkerFlag.cmake35
-rw-r--r--Modules/Platform/Windows-IntelLLVM.cmake13
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/LexerParser/cmGccDepfileLexer.cxx115
-rw-r--r--Source/LexerParser/cmGccDepfileLexer.h7
-rw-r--r--Source/LexerParser/cmGccDepfileLexer.in.l11
-rw-r--r--Source/cmDependsCompiler.cxx9
-rw-r--r--Source/cmGccDepfileLexerHelper.cxx40
-rw-r--r--Source/cmTransformDepfile.cxx17
-rw-r--r--Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake9
-rw-r--r--Tests/RunCMake/BuildDepends/CustomCommandDepfile.step1.cmake1
-rw-r--r--Tests/RunCMake/BuildDepends/CustomCommandDepfile.step2.cmake1
-rw-r--r--Tests/RunCMake/BuildDepends/WriteDepfile2.cmake8
-rw-r--r--Tests/RunCMake/CheckCompilerFlag/NonExistentLanguage-stderr.txt2
-rw-r--r--Tests/RunCMake/CheckCompilerFlag/NotEnabledLanguage-stderr.txt2
-rw-r--r--Tests/RunCMake/find_library/FromPATHEnv.cmake3
-rw-r--r--Tests/RunCMake/find_library/FromPATHEnvDebugVar.cmake3
-rw-r--r--Tests/RunCMake/find_library/FromPrefixPath.cmake3
-rwxr-xr-xUtilities/Scripts/update-expat.bash2
-rw-r--r--Utilities/cmexpat/ConfigureChecks.cmake1
-rw-r--r--Utilities/cmexpat/README.md2
-rw-r--r--Utilities/cmexpat/lib/expat.h4
-rw-r--r--Utilities/cmexpat/lib/xmlparse.c212
-rw-r--r--Utilities/cmexpat/lib/xmlrole.c5
-rw-r--r--Utilities/cmexpat/lib/xmltok.c5
-rw-r--r--Utilities/cmexpat/lib/xmltok_ns.c4
39 files changed, 530 insertions, 243 deletions
diff --git a/Copyright.txt b/Copyright.txt
index ed25419..4b6a7f5 100644
--- a/Copyright.txt
+++ b/Copyright.txt
@@ -62,6 +62,7 @@ The following individuals and institutions are among the Contributors:
* Helio Chissini de Castro <helio@kde.org>
* Ilya Lavrenov <ilya.lavrenov@itseez.com>
* Insight Software Consortium <insightsoftwareconsortium.org>
+* Intel Corporation <www.intel.com>
* Jan Woetzel
* Jordan Williams <jordan@jwillikers.com>
* Julien Schueller
diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst
index f07b4a6..ec73f9f 100644
--- a/Help/command/add_custom_command.rst
+++ b/Help/command/add_custom_command.rst
@@ -288,11 +288,10 @@ The options are:
.. productionlist:: depfile
depfile: `rule`*
- rule: `targets` (`colon` `dependencies`?)? `eol`
- colon: `separator`* ':' space `separator`*
- targets: `target` (`separator` `target`)*
+ rule: `targets` (`:` (`separator` `dependencies`?)?)? `eol`
+ targets: `target` (`separator` `target`)* `separator`*
target: `pathname`
- dependencies: `dependency` (`separator` `dependency`)*
+ dependencies: `dependency` (`separator` `dependency`)* `separator`*
dependency: `pathname`
separator: (space | line_continue)+
line_continue: '\' `eol`
diff --git a/Help/envvar/CUDAARCHS.rst b/Help/envvar/CUDAARCHS.rst
index 82369cd..e9e6a42 100644
--- a/Help/envvar/CUDAARCHS.rst
+++ b/Help/envvar/CUDAARCHS.rst
@@ -6,8 +6,7 @@ CUDAARCHS
.. include:: ENV_VAR.txt
Value used to initialize :variable:`CMAKE_CUDA_ARCHITECTURES` on the first
-configuration if it's not already defined. Subsequent runs will use the value
-stored in the cache.
+configuration. Subsequent runs will use the value stored in the cache.
This is a semicolon-separated list of architectures as described in
:prop_tgt:`CUDA_ARCHITECTURES`.
diff --git a/Help/envvar/CUDAHOSTCXX.rst b/Help/envvar/CUDAHOSTCXX.rst
index cf65927..74f5d48 100644
--- a/Help/envvar/CUDAHOSTCXX.rst
+++ b/Help/envvar/CUDAHOSTCXX.rst
@@ -8,9 +8,8 @@ CUDAHOSTCXX
Preferred executable for compiling host code when compiling ``CUDA``
language files. Will only be used by CMake on the first configuration to
determine ``CUDA`` host compiler, after which the value for ``CUDAHOSTCXX`` is
-stored in the cache as :variable:`CMAKE_CUDA_HOST_COMPILER`. For any
-configuration run (including the first), the environment variable will be
-ignored if the :variable:`CMAKE_CUDA_HOST_COMPILER` variable is defined.
+stored in the cache as :variable:`CMAKE_CUDA_HOST_COMPILER`. This environment
+variable is preferred over :variable:`CMAKE_CUDA_HOST_COMPILER`.
This environment variable is primarily meant for use with projects that
enable ``CUDA`` as a first-class language.
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 51b092f..920bfe0 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -581,8 +581,6 @@ Variables for Languages
/variable/CMAKE_LANG_IMPLICIT_LINK_LIBRARIES
/variable/CMAKE_LANG_LIBRARY_ARCHITECTURE
/variable/CMAKE_LANG_LINK_EXECUTABLE
- /variable/CMAKE_LANG_LINKER_PREFERENCE
- /variable/CMAKE_LANG_LINKER_PREFERENCE_PROPAGATES
/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG
/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG_SEP
/variable/CMAKE_LANG_OUTPUT_EXTENSION
@@ -727,6 +725,8 @@ are subject to change, and not recommended for use in project code.
/variable/CMAKE_LANG_COMPILER_ABI
/variable/CMAKE_LANG_COMPILER_ARCHITECTURE_ID
/variable/CMAKE_LANG_COMPILER_VERSION_INTERNAL
+ /variable/CMAKE_LANG_LINKER_PREFERENCE
+ /variable/CMAKE_LANG_LINKER_PREFERENCE_PROPAGATES
/variable/CMAKE_LANG_PLATFORM_ID
/variable/CMAKE_NOT_USING_CONFIG_FLAGS
/variable/CMAKE_VS_INTEL_Fortran_PROJECT_VERSION
diff --git a/Help/prop_tgt/LANG_STANDARD.rst b/Help/prop_tgt/LANG_STANDARD.rst
index bd377ec..c83da01 100644
--- a/Help/prop_tgt/LANG_STANDARD.rst
+++ b/Help/prop_tgt/LANG_STANDARD.rst
@@ -15,6 +15,13 @@ newer standard is specified than is supported by the compiler, then it will
fallback to the latest supported standard. This "decay" behavior may be
controlled with the :prop_tgt:`<LANG>_STANDARD_REQUIRED` target property.
+Note that the actual language standard used may be higher than that specified
+by ``<LANG>_STANDARD``, regardless of the value of
+:prop_tgt:`<LANG>_STANDARD_REQUIRED`. In particular,
+:ref:`transitive usage requirements <Target Usage Requirements>` or the use of
+:manual:`compile features <cmake-compile-features(7)>` can raise the required
+language standard above what ``<LANG>_STANDARD`` specifies.
+
These properties are initialized by the value of the
:variable:`CMAKE_<LANG>_STANDARD` variable if it is set when a target is
created.
diff --git a/Help/prop_tgt/LANG_STANDARD_REQUIRED.rst b/Help/prop_tgt/LANG_STANDARD_REQUIRED.rst
index 56ecef8..e61125b 100644
--- a/Help/prop_tgt/LANG_STANDARD_REQUIRED.rst
+++ b/Help/prop_tgt/LANG_STANDARD_REQUIRED.rst
@@ -11,16 +11,22 @@ The variations are:
* :prop_tgt:`OBJCXX_STANDARD_REQUIRED`
These properties specify whether the value of :prop_tgt:`<LANG>_STANDARD` is a
-requirement. When ``OFF`` or unset, the :prop_tgt:`<LANG>_STANDARD` target
+requirement. When false or unset, the :prop_tgt:`<LANG>_STANDARD` target
property is treated as optional and may "decay" to a previous standard if the
-requested is not available.
+requested standard is not available. When ``<LANG>_STANDARD_REQUIRED`` is set
+to true, :prop_tgt:`<LANG>_STANDARD` becomes a hard requirement and a fatal
+error will be issued if that requirement cannot be met.
+
+Note that the actual language standard used may be higher than that specified
+by :prop_tgt:`<LANG>_STANDARD`, regardless of the value of
+``<LANG>_STANDARD_REQUIRED``. In particular,
+:ref:`transitive usage requirements <Target Usage Requirements>` or the use of
+:manual:`compile features <cmake-compile-features(7)>` can raise the required
+language standard above what :prop_tgt:`<LANG>_STANDARD` specifies.
These properties are initialized by the value of the
:variable:`CMAKE_<LANG>_STANDARD_REQUIRED` variable if it is set when a target
is created.
-For supported CMake versions see the respective pages.
-To control language standard versions see :prop_tgt:`<LANG>_STANDARD`.
-
See the :manual:`cmake-compile-features(7)` manual for information on
compile features and a list of supported compilers.
diff --git a/Help/variable/CMAKE_LANG_LINKER_PREFERENCE.rst b/Help/variable/CMAKE_LANG_LINKER_PREFERENCE.rst
index ff82f8b..a4035bd 100644
--- a/Help/variable/CMAKE_LANG_LINKER_PREFERENCE.rst
+++ b/Help/variable/CMAKE_LANG_LINKER_PREFERENCE.rst
@@ -1,6 +1,8 @@
CMAKE_<LANG>_LINKER_PREFERENCE
------------------------------
+An internal variable subject to change.
+
Preference value for linker language selection.
The "linker language" for executable, shared library, and module
diff --git a/Help/variable/CMAKE_LANG_LINKER_PREFERENCE_PROPAGATES.rst b/Help/variable/CMAKE_LANG_LINKER_PREFERENCE_PROPAGATES.rst
index dbbeb0a..df33edb 100644
--- a/Help/variable/CMAKE_LANG_LINKER_PREFERENCE_PROPAGATES.rst
+++ b/Help/variable/CMAKE_LANG_LINKER_PREFERENCE_PROPAGATES.rst
@@ -1,6 +1,8 @@
CMAKE_<LANG>_LINKER_PREFERENCE_PROPAGATES
-----------------------------------------
+An internal variable subject to change.
+
True if :variable:`CMAKE_<LANG>_LINKER_PREFERENCE` propagates across targets.
This is used when CMake selects a linker language for a target.
diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake
index 8479831..df71799 100644
--- a/Modules/CMakeDetermineCUDACompiler.cmake
+++ b/Modules/CMakeDetermineCUDACompiler.cmake
@@ -18,16 +18,16 @@ else()
if(NOT CMAKE_CUDA_COMPILER)
set(CMAKE_CUDA_COMPILER_INIT NOTFOUND)
- # prefer the environment variable CUDACXX
- if(NOT $ENV{CUDACXX} STREQUAL "")
- get_filename_component(CMAKE_CUDA_COMPILER_INIT $ENV{CUDACXX} PROGRAM PROGRAM_ARGS CMAKE_CUDA_FLAGS_ENV_INIT)
- if(CMAKE_CUDA_FLAGS_ENV_INIT)
- set(CMAKE_CUDA_COMPILER_ARG1 "${CMAKE_CUDA_FLAGS_ENV_INIT}" CACHE STRING "Arguments to CXX compiler")
- endif()
- if(NOT EXISTS ${CMAKE_CUDA_COMPILER_INIT})
- message(FATAL_ERROR "Could not find compiler set in environment variable CUDACXX:\n$ENV{CUDACXX}.\n${CMAKE_CUDA_COMPILER_INIT}")
- endif()
+ # prefer the environment variable CUDACXX
+ if(NOT $ENV{CUDACXX} STREQUAL "")
+ get_filename_component(CMAKE_CUDA_COMPILER_INIT $ENV{CUDACXX} PROGRAM PROGRAM_ARGS CMAKE_CUDA_FLAGS_ENV_INIT)
+ if(CMAKE_CUDA_FLAGS_ENV_INIT)
+ set(CMAKE_CUDA_COMPILER_ARG1 "${CMAKE_CUDA_FLAGS_ENV_INIT}" CACHE STRING "Arguments to CUDA compiler")
endif()
+ if(NOT EXISTS ${CMAKE_CUDA_COMPILER_INIT})
+ message(FATAL_ERROR "Could not find compiler set in environment variable CUDACXX:\n$ENV{CUDACXX}.\n${CMAKE_CUDA_COMPILER_INIT}")
+ endif()
+ endif()
# finally list compilers to try
if(NOT CMAKE_CUDA_COMPILER_INIT)
diff --git a/Modules/CheckLinkerFlag.cmake b/Modules/CheckLinkerFlag.cmake
index e85e43e..8319216 100644
--- a/Modules/CheckLinkerFlag.cmake
+++ b/Modules/CheckLinkerFlag.cmake
@@ -38,53 +38,8 @@ effect or even a specific one is beyond the scope of this module.
#]=======================================================================]
include_guard(GLOBAL)
-
-include(CMakeCheckCompilerFlagCommonPatterns)
-
-cmake_policy(PUSH)
-cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced
-cmake_policy(SET CMP0057 NEW) # if() supports IN_LIST
+include(Internal/CheckLinkerFlag)
function(CHECK_LINKER_FLAG _lang _flag _var)
- get_property (_supported_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
- if (NOT _lang IN_LIST _supported_languages)
- message (SEND_ERROR "check_linker_flag: ${_lang}: unknown language.")
- return()
- endif()
-
- include (CheckSourceCompiles)
-
- set(CMAKE_REQUIRED_LINK_OPTIONS "${_flag}")
-
- # Normalize locale during test compilation.
- set(_locale_vars LC_ALL LC_MESSAGES LANG)
- foreach(v IN LISTS _locale_vars)
- set(_locale_vars_saved_${v} "$ENV{${v}}")
- set(ENV{${v}} C)
- endforeach()
-
- if (_lang MATCHES "^(C|CXX)$")
- set (_source "int main() { return 0; }")
- elseif (_lang STREQUAL "Fortran")
- set (_source " program test\n stop\n end program")
- elseif (_lang MATCHES "CUDA")
- set (_source "__host__ int main() { return 0; }")
- elseif (_lang MATCHES "HIP")
- set (_source "__host__ int main() { return 0; }")
- elseif (_lang MATCHES "^(OBJC|OBJCXX)$")
- set (_source "#ifndef __OBJC__\n# error \"Not an Objective-C++ compiler\"\n#endif\nint main(void) { return 0; }")
- else()
- message (SEND_ERROR "check_linker_flag: ${_lang}: unsupported language.")
- return()
- endif()
- check_compiler_flag_common_patterns(_common_patterns)
-
- check_source_compiles(${_lang} "${_source}" ${_var} ${_common_patterns})
-
- foreach(v IN LISTS _locale_vars)
- set(ENV{${v}} ${_locale_vars_saved_${v}})
- endforeach()
- set(${_var} "${${_var}}" PARENT_SCOPE)
+ cmake_check_linker_flag(${_lang} "${_flag}" ${_var})
endfunction()
-
-cmake_policy(POP)
diff --git a/Modules/Internal/CheckCompilerFlag.cmake b/Modules/Internal/CheckCompilerFlag.cmake
index f6a4cc9..3a67691 100644
--- a/Modules/Internal/CheckCompilerFlag.cmake
+++ b/Modules/Internal/CheckCompilerFlag.cmake
@@ -2,71 +2,15 @@
# file Copyright.txt or https://cmake.org/licensing for details.
include_guard(GLOBAL)
+include(Internal/CheckFlagCommonConfig)
include(Internal/CheckSourceCompiles)
include(CMakeCheckCompilerFlagCommonPatterns)
-cmake_policy(PUSH)
-cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced
-cmake_policy(SET CMP0057 NEW) # if() supports IN_LIST
-
function(CMAKE_CHECK_COMPILER_FLAG _lang _flag _var)
-
- if(_lang STREQUAL "C")
- set(_lang_src "int main(void) { return 0; }")
- set(_lang_fail_regex FAIL_REGEX "command[ -]line option .* is valid for .* but not for C"
- FAIL_REGEX "-Werror=.* argument .* is not valid for C")
- elseif(_lang STREQUAL "CXX")
- set(_lang_src "int main() { return 0; }")
- set(_lang_fail_regex FAIL_REGEX "command[ -]line option .* is valid for .* but not for C\\+\\+"
- FAIL_REGEX "-Werror=.* argument .* is not valid for C\\+\\+")
- elseif(_lang STREQUAL "CUDA")
- set(_lang_src "__host__ int main() { return 0; }")
- set(_lang_fail_regex FAIL_REGEX "command[ -]line option .* is valid for .* but not for C\\+\\+" # Host GNU
- FAIL_REGEX "argument unused during compilation: .*") # Clang
- elseif(_lang STREQUAL "Fortran")
- set(_lang_src " program test\n stop\n end program")
- set(_lang_fail_regex FAIL_REGEX "command[ -]line option .* is valid for .* but not for Fortran")
- elseif(_lang STREQUAL "HIP")
- set(_lang_src "__host__ int main() { return 0; }")
- set(_lang_fail_regex FAIL_REGEX "argument unused during compilation: .*") # Clang
- elseif(_lang STREQUAL "OBJC")
- set(_lang_src [=[
-#ifndef __OBJC__
-# error "Not an Objective-C compiler"
-#endif
-int main(void) { return 0; }]=])
- set(_lang_fail_regex FAIL_REGEX "command[ -]line option .* is valid for .* but not for Objective-C" # GNU
- FAIL_REGEX "argument unused during compilation: .*") # Clang
- elseif(_lang STREQUAL "OBJCXX")
- set(_lang_src [=[
-#ifndef __OBJC__
-# error "Not an Objective-C++ compiler"
-#endif
-int main(void) { return 0; }]=])
- set(_lang_fail_regex FAIL_REGEX "command[ -]line option .* is valid for .* but not for Objective-C\\+\\+" # GNU
- FAIL_REGEX "argument unused during compilation: .*") # Clang
- elseif(_lang STREQUAL "ISPC")
- set(_lang_src "float func(uniform int32, float a) { return a / 2.25; }")
- else()
- message (SEND_ERROR "check_compiler_flag: ${_lang}: unknown language.")
- return()
- endif()
-
- get_property (_supported_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
- if (NOT _lang IN_LIST _supported_languages)
- message (SEND_ERROR "check_compiler_flag: ${_lang}: needs to be enabled before use.")
- return()
- endif()
+ cmake_check_flag_common_init("check_compiler_flag" ${_lang} _lang_src _lang_fail_regex)
set(CMAKE_REQUIRED_DEFINITIONS ${_flag})
- # Normalize locale during test compilation.
- set(_locale_vars LC_ALL LC_MESSAGES LANG)
- foreach(v IN LISTS _locale_vars)
- set(_locale_vars_saved_${v} "$ENV{${v}}")
- set(ENV{${v}} C)
- endforeach()
-
check_compiler_flag_common_patterns(_common_patterns)
cmake_check_source_compiles(${_lang}
"${_lang_src}"
@@ -75,9 +19,5 @@ int main(void) { return 0; }]=])
${_common_patterns}
)
- foreach(v IN LISTS _locale_vars)
- set(ENV{${v}} ${_locale_vars_saved_${v}})
- endforeach()
-endfunction ()
-
-cmake_policy(POP)
+ cmake_check_flag_common_finish()
+endfunction()
diff --git a/Modules/Internal/CheckFlagCommonConfig.cmake b/Modules/Internal/CheckFlagCommonConfig.cmake
new file mode 100644
index 0000000..3934c02
--- /dev/null
+++ b/Modules/Internal/CheckFlagCommonConfig.cmake
@@ -0,0 +1,75 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+
+# Do NOT include this module directly into any of your code. It is meant as
+# a library for Check*CompilerFlag.cmake and Check*LinkerFlag.cma modules.
+# It's content may change in any way between releases.
+
+include_guard(GLOBAL)
+cmake_policy(PUSH)
+cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced
+cmake_policy(SET CMP0057 NEW) # if() supports IN_LIST
+
+macro(CMAKE_CHECK_FLAG_COMMON_INIT _FUNC _LANG _SRC _PATTERNS)
+ if("${_LANG}" STREQUAL "C")
+ set(${_SRC} "int main(void) { return 0; }")
+ set(${_PATTERNS} FAIL_REGEX "command[ -]line option .* is valid for .* but not for C"
+ FAIL_REGEX "-Werror=.* argument .* is not valid for C")
+ elseif("${_LANG}" STREQUAL "CXX")
+ set(${_SRC} "int main() { return 0; }")
+ set(${_PATTERNS} FAIL_REGEX "command[ -]line option .* is valid for .* but not for C\\+\\+"
+ FAIL_REGEX "-Werror=.* argument .* is not valid for C\\+\\+")
+ elseif("${_LANG}" STREQUAL "CUDA")
+ set(${_SRC} "__host__ int main() { return 0; }")
+ set(${_PATTERNS} FAIL_REGEX "command[ -]line option .* is valid for .* but not for C\\+\\+" # Host GNU
+ FAIL_REGEX "argument unused during compilation: .*") # Clang
+ elseif("${_LANG}" STREQUAL "Fortran")
+ set(${_SRC} " program test\n stop\n end program")
+ set(${_PATTERNS} FAIL_REGEX "command[ -]line option .* is valid for .* but not for Fortran")
+ elseif("${_LANG}" STREQUAL "HIP")
+ set(${_SRC} "__host__ int main() { return 0; }")
+ set(${_PATTERNS} FAIL_REGEX "argument unused during compilation: .*") # Clang
+ elseif("${_LANG}" STREQUAL "OBJC")
+ set(${_SRC} [=[
+ #ifndef __OBJC__
+ # error "Not an Objective-C compiler"
+ #endif
+ int main(void) { return 0; }]=])
+ set(${_PATTERNS} FAIL_REGEX "command[ -]line option .* is valid for .* but not for Objective-C" # GNU
+ FAIL_REGEX "argument unused during compilation: .*") # Clang
+ elseif("${_LANG}" STREQUAL "OBJCXX")
+ set(${_SRC} [=[
+ #ifndef __OBJC__
+ # error "Not an Objective-C++ compiler"
+ #endif
+ int main(void) { return 0; }]=])
+ set(${_PATTERNS} FAIL_REGEX "command[ -]line option .* is valid for .* but not for Objective-C\\+\\+" # GNU
+ FAIL_REGEX "argument unused during compilation: .*") # Clang
+ elseif("${_LANG}" STREQUAL "ISPC")
+ set(${_SRC} "float func(uniform int32, float a) { return a / 2.25; }")
+ else()
+ message (SEND_ERROR "${_FUNC}: ${_LANG}: unknown language.")
+ return()
+ endif()
+
+ get_property (_supported_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
+ if (NOT "${_LANG}" IN_LIST _supported_languages)
+ message (SEND_ERROR "${_FUNC}: ${_LANG}: needs to be enabled before use.")
+ return()
+ endif()
+ # Normalize locale during test compilation.
+ set(_locale_vars LC_ALL LC_MESSAGES LANG)
+ foreach(v IN LISTS _locale_vars)
+ set(_CMAKE_CHECK_FLAG_COMMON_CONFIG_locale_vars_saved_${v} "$ENV{${v}}")
+ set(ENV{${v}} C)
+ endforeach()
+endmacro()
+
+macro(CMAKE_CHECK_FLAG_COMMON_FINISH)
+ foreach(v IN LISTS _CFCC_locale_vars)
+ set(ENV{${v}} ${_CMAKE_CHECK_FLAG_COMMON_CONFIG_locale_vars_saved_${v}})
+ endforeach()
+endmacro()
+
+cmake_policy(POP)
diff --git a/Modules/Internal/CheckLinkerFlag.cmake b/Modules/Internal/CheckLinkerFlag.cmake
new file mode 100644
index 0000000..285372a
--- /dev/null
+++ b/Modules/Internal/CheckLinkerFlag.cmake
@@ -0,0 +1,35 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+include_guard(GLOBAL)
+include(Internal/CheckFlagCommonConfig)
+include(Internal/CheckSourceCompiles)
+include(CMakeCheckCompilerFlagCommonPatterns)
+
+cmake_policy(PUSH)
+cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced
+
+function(CMAKE_CHECK_LINKER_FLAG _lang _flag _var)
+ # link step supports less languages than the compiler
+ # so do a first check about the requested language
+ if (_lang STREQUAL "ISPC")
+ message (SEND_ERROR "check_linker_flag: ${_lang}: unsupported language.")
+ return()
+ endif()
+
+ cmake_check_flag_common_init("check_linker_flag" ${_lang} _lang_src _lang_fail_regex)
+
+ set(CMAKE_REQUIRED_LINK_OPTIONS "${_flag}")
+
+ check_compiler_flag_common_patterns(_common_patterns)
+ cmake_check_source_compiles(${_lang}
+ "${_lang_src}"
+ ${_var}
+ ${_lang_fail_regex}
+ ${_common_patterns}
+ )
+
+ cmake_check_flag_common_finish()
+endfunction()
+
+cmake_policy(POP)
diff --git a/Modules/Platform/Windows-IntelLLVM.cmake b/Modules/Platform/Windows-IntelLLVM.cmake
index b9ea037..4687bee 100644
--- a/Modules/Platform/Windows-IntelLLVM.cmake
+++ b/Modules/Platform/Windows-IntelLLVM.cmake
@@ -12,6 +12,19 @@ include(Platform/Windows-MSVC)
macro(__windows_compiler_intel lang)
__windows_compiler_msvc(${lang})
+ # For DPCPP other offload cases, some link flags need to go to the compiler
+ # driver and others need to go to the linker. Pass the compiler linking flags
+ # in CMAKE_${lang}_LINK_FLAGS and linker flags in LINK_FLAGS
+ set(CMAKE_${lang}_LINK_EXECUTABLE
+ "${_CMAKE_VS_LINK_EXE}<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} <CMAKE_${lang}_LINK_FLAGS> <OBJECTS> ${CMAKE_START_TEMP_FILE} /link /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
+ set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
+ "${_CMAKE_VS_LINK_DLL}<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} <CMAKE_${lang}_LINK_FLAGS> <OBJECTS> ${CMAKE_START_TEMP_FILE} -LD -link /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
+ if (NOT "${lang}" STREQUAL "Fortran" OR CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 2022.1)
+ # The Fortran driver does not support -fuse-ld=llvm-lib before compiler version 2022.1
+ set(CMAKE_${lang}_CREATE_STATIC_LIBRARY
+ "<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} <CMAKE_${lang}_LINK_FLAGS> <OBJECTS> ${CMAKE_START_TEMP_FILE} -fuse-ld=llvm-lib -o <TARGET> -link <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
+ endif()
+
set(CMAKE_DEPFILE_FLAGS_${lang} "-QMMD -QMT <DEP_TARGET> -QMF <DEP_FILE>")
set(CMAKE_${lang}_DEPFILE_FORMAT gcc)
endmacro()
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 0733b07..1e65a88 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 22)
-set(CMake_VERSION_PATCH 20220114)
+set(CMake_VERSION_PATCH 20220119)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/LexerParser/cmGccDepfileLexer.cxx b/Source/LexerParser/cmGccDepfileLexer.cxx
index 194ae0c..e588853 100644
--- a/Source/LexerParser/cmGccDepfileLexer.cxx
+++ b/Source/LexerParser/cmGccDepfileLexer.cxx
@@ -256,6 +256,7 @@ typedef int16_t flex_int16_t;
typedef uint16_t flex_uint16_t;
typedef int32_t flex_int32_t;
typedef uint32_t flex_uint32_t;
+typedef uint64_t flex_uint64_t;
#else
typedef signed char flex_int8_t;
typedef short int flex_int16_t;
@@ -420,7 +421,7 @@ struct yy_buffer_state
/* Number of characters read into yy_ch_buf, not including EOB
* characters.
*/
- int yy_n_chars;
+ yy_size_t yy_n_chars;
/* Whether we "own" the buffer - i.e., we know we created it,
* and can realloc() it to grow it, and should free() it to
@@ -497,7 +498,7 @@ static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner
YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner );
YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner );
-YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, yy_size_t len , yyscan_t yyscanner );
void *yyalloc ( yy_size_t , yyscan_t yyscanner );
void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner );
@@ -544,12 +545,12 @@ static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner );
*/
#define YY_DO_BEFORE_ACTION \
yyg->yytext_ptr = yy_bp; \
- yyleng = (int) (yy_cp - yy_bp); \
+ yyleng = (yy_size_t) (yy_cp - yy_bp); \
yyg->yy_hold_char = *yy_cp; \
*yy_cp = '\0'; \
yyg->yy_c_buf_p = yy_cp;
-#define YY_NUM_RULES 11
-#define YY_END_OF_BUFFER 12
+#define YY_NUM_RULES 12
+#define YY_END_OF_BUFFER 13
/* This struct is not used in this scanner,
but its presence is necessary. */
struct yy_trans_info
@@ -557,11 +558,11 @@ struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static const flex_int16_t yy_accept[26] =
+static const flex_int16_t yy_accept[31] =
{ 0,
- 0, 0, 12, 10, 8, 6, 10, 9, 10, 10,
- 10, 8, 0, 6, 9, 1, 7, 5, 0, 3,
- 2, 0, 4, 0, 0
+ 0, 0, 13, 11, 9, 6, 11, 10, 11, 11,
+ 11, 9, 0, 6, 10, 1, 8, 7, 0, 0,
+ 5, 0, 3, 2, 0, 8, 0, 4, 0, 0
} ;
static const YY_CHAR yy_ec[256] =
@@ -601,36 +602,40 @@ static const YY_CHAR yy_meta[11] =
1, 2, 1, 1, 2, 1, 1, 1, 1, 3
} ;
-static const flex_int16_t yy_base[28] =
+static const flex_int16_t yy_base[33] =
{ 0,
- 0, 0, 29, 35, 18, 35, 22, 18, 15, 0,
- 8, 12, 16, 35, 11, 35, 0, 35, 13, 35,
- 35, 16, 35, 22, 35, 31, 12
+ 0, 0, 36, 46, 25, 46, 31, 27, 18, 9,
+ 17, 15, 25, 46, 17, 46, 0, 46, 15, 27,
+ 46, 14, 46, 46, 27, 46, 13, 46, 33, 46,
+ 42, 13
} ;
-static const flex_int16_t yy_def[28] =
+static const flex_int16_t yy_def[33] =
{ 0,
- 25, 1, 25, 25, 26, 25, 25, 25, 25, 27,
- 25, 26, 25, 25, 25, 25, 27, 25, 25, 25,
- 25, 25, 25, 25, 0, 25, 25
+ 30, 1, 30, 30, 31, 30, 30, 30, 30, 30,
+ 30, 31, 30, 30, 30, 30, 32, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 0,
+ 30, 30
} ;
-static const flex_int16_t yy_nxt[46] =
+static const flex_int16_t yy_nxt[57] =
{ 0,
4, 5, 6, 7, 5, 8, 4, 9, 10, 11,
- 18, 19, 20, 17, 21, 18, 15, 22, 18, 19,
- 23, 13, 16, 15, 14, 24, 20, 13, 25, 25,
- 25, 22, 12, 12, 3, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25
+ 17, 18, 19, 17, 17, 26, 21, 18, 20, 21,
+ 22, 23, 15, 24, 13, 16, 25, 21, 22, 26,
+ 27, 28, 15, 14, 13, 30, 29, 23, 30, 30,
+ 30, 30, 25, 12, 12, 3, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30
} ;
-static const flex_int16_t yy_chk[46] =
+static const flex_int16_t yy_chk[57] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 11, 11, 11, 27, 11, 19, 15, 11, 13, 13,
- 22, 12, 9, 8, 7, 22, 24, 5, 3, 0,
- 0, 24, 26, 26, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25
+ 10, 10, 10, 10, 32, 27, 22, 19, 10, 11,
+ 11, 11, 15, 11, 12, 9, 11, 13, 13, 20,
+ 20, 25, 8, 7, 5, 3, 25, 29, 0, 0,
+ 0, 0, 29, 31, 31, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30
} ;
/* The intent behind this definition is that it'll catch
@@ -669,8 +674,8 @@ struct yyguts_t
size_t yy_buffer_stack_max; /**< capacity of stack. */
YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
char yy_hold_char;
- int yy_n_chars;
- int yyleng_r;
+ yy_size_t yy_n_chars;
+ yy_size_t yyleng_r;
char *yy_c_buf_p;
int yy_init;
int yy_start;
@@ -717,7 +722,7 @@ FILE *yyget_out ( yyscan_t yyscanner );
void yyset_out ( FILE * _out_str , yyscan_t yyscanner );
- int yyget_leng ( yyscan_t yyscanner );
+ yy_size_t yyget_leng ( yyscan_t yyscanner );
char *yyget_text ( yyscan_t yyscanner );
@@ -790,7 +795,7 @@ static int input ( yyscan_t yyscanner );
if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
{ \
int c = '*'; \
- int n; \
+ yy_size_t n; \
for ( n = 0; n < max_size && \
(c = getc( yyin )) != EOF && c != '\n'; ++n ) \
buf[n] = (char) c; \
@@ -926,13 +931,13 @@ yy_match:
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 26 )
+ if ( yy_current_state >= 31 )
yy_c = yy_meta[yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
++yy_cp;
}
- while ( yy_base[yy_current_state] != 35 );
+ while ( yy_base[yy_current_state] != 46 );
yy_find_action:
yy_act = yy_accept[yy_current_state];
@@ -1006,34 +1011,46 @@ YY_RULE_SETUP
}
YY_BREAK
case 7:
+/* rule 7 can match eol */
YY_RULE_SETUP
{
- // A colon followed by space ends the rules and starts a new dependency.
+ // A colon ends the rules
yyextra->newDependency();
+ // A newline after colon terminates current rule.
+ yyextra->newEntry();
}
YY_BREAK
case 8:
+/* rule 8 can match eol */
+YY_RULE_SETUP
+{
+ // A colon followed by space or line continuation ends the rules
+ // and starts a new dependency.
+ yyextra->newDependency();
+ }
+ YY_BREAK
+case 9:
YY_RULE_SETUP
{
// Rules and dependencies are separated by blocks of whitespace.
yyextra->newRuleOrDependency();
}
YY_BREAK
-case 9:
+case 10:
YY_RULE_SETUP
{
// Got a span of plain text.
yyextra->addToCurrentPath(yytext);
}
YY_BREAK
-case 10:
+case 11:
YY_RULE_SETUP
{
// Got an otherwise unmatched character.
yyextra->addToCurrentPath(yytext);
}
YY_BREAK
-case 11:
+case 12:
YY_RULE_SETUP
ECHO;
YY_BREAK
@@ -1224,7 +1241,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
else
{
- int num_to_read =
+ yy_size_t num_to_read =
YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
while ( num_to_read <= 0 )
@@ -1238,7 +1255,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
if ( b->yy_is_our_buffer )
{
- int new_size = b->yy_buf_size * 2;
+ yy_size_t new_size = b->yy_buf_size * 2;
if ( new_size <= 0 )
b->yy_buf_size += b->yy_buf_size / 8;
@@ -1296,7 +1313,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
/* Extend the array by 50%, plus the number we really need. */
- int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+ yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(
(void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner );
if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
@@ -1335,7 +1352,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 26 )
+ if ( yy_current_state >= 31 )
yy_c = yy_meta[yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
@@ -1364,11 +1381,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 26 )
+ if ( yy_current_state >= 31 )
yy_c = yy_meta[yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
- yy_is_jam = (yy_current_state == 25);
+ yy_is_jam = (yy_current_state == 30);
(void)yyg;
return yy_is_jam ? 0 : yy_current_state;
@@ -1389,7 +1406,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
{ /* need to shift things up to make room */
/* +2 for EOB chars. */
- int number_to_move = yyg->yy_n_chars + 2;
+ yy_size_t number_to_move = yyg->yy_n_chars + 2;
char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
char *source =
@@ -1441,7 +1458,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
else
{ /* need more input */
- int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr);
+ yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
++yyg->yy_c_buf_p;
switch ( yy_get_next_buffer( yyscanner ) )
@@ -1819,12 +1836,12 @@ YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner)
* @param yyscanner The scanner object.
* @return the newly allocated buffer state object.
*/
-YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len , yyscan_t yyscanner)
+YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, yy_size_t _yybytes_len , yyscan_t yyscanner)
{
YY_BUFFER_STATE b;
char *buf;
yy_size_t n;
- int i;
+ yy_size_t i;
/* Get memory for full buffer, including space for trailing EOB's. */
n = (yy_size_t) (_yybytes_len + 2);
@@ -1868,7 +1885,7 @@ static void yynoreturn yy_fatal_error (const char* msg , yyscan_t yyscanner)
do \
{ \
/* Undo effects of setting up yytext. */ \
- int yyless_macro_arg = (n); \
+ yy_size_t yyless_macro_arg = (n); \
YY_LESS_LINENO(yyless_macro_arg);\
yytext[yyleng] = yyg->yy_hold_char; \
yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
@@ -1936,7 +1953,7 @@ FILE *yyget_out (yyscan_t yyscanner)
/** Get the length of the current token.
* @param yyscanner The scanner object.
*/
-int yyget_leng (yyscan_t yyscanner)
+yy_size_t yyget_leng (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyleng;
diff --git a/Source/LexerParser/cmGccDepfileLexer.h b/Source/LexerParser/cmGccDepfileLexer.h
index 7d34060..ab73ebc 100644
--- a/Source/LexerParser/cmGccDepfileLexer.h
+++ b/Source/LexerParser/cmGccDepfileLexer.h
@@ -258,6 +258,7 @@ typedef int16_t flex_int16_t;
typedef uint16_t flex_uint16_t;
typedef int32_t flex_int32_t;
typedef uint32_t flex_uint32_t;
+typedef uint64_t flex_uint64_t;
#else
typedef signed char flex_int8_t;
typedef short int flex_int16_t;
@@ -371,7 +372,7 @@ struct yy_buffer_state
/* Number of characters read into yy_ch_buf, not including EOB
* characters.
*/
- int yy_n_chars;
+ yy_size_t yy_n_chars;
/* Whether we "own" the buffer - i.e., we know we created it,
* and can realloc() it to grow it, and should free() it to
@@ -415,7 +416,7 @@ void yypop_buffer_state ( yyscan_t yyscanner );
YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner );
YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner );
-YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, yy_size_t len , yyscan_t yyscanner );
void *yyalloc ( yy_size_t , yyscan_t yyscanner );
void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner );
@@ -462,7 +463,7 @@ FILE *yyget_out ( yyscan_t yyscanner );
void yyset_out ( FILE * _out_str , yyscan_t yyscanner );
- int yyget_leng ( yyscan_t yyscanner );
+ yy_size_t yyget_leng ( yyscan_t yyscanner );
char *yyget_text ( yyscan_t yyscanner );
diff --git a/Source/LexerParser/cmGccDepfileLexer.in.l b/Source/LexerParser/cmGccDepfileLexer.in.l
index aa2351e..6336b5f 100644
--- a/Source/LexerParser/cmGccDepfileLexer.in.l
+++ b/Source/LexerParser/cmGccDepfileLexer.in.l
@@ -48,8 +48,15 @@ NEWLINE \r?\n
// A newline ends the current file name and the current rule.
yyextra->newEntry();
}
-:{WSPACE}+ {
- // A colon followed by space ends the rules and starts a new dependency.
+:{NEWLINE} {
+ // A colon ends the rules
+ yyextra->newDependency();
+ // A newline after colon terminates current rule.
+ yyextra->newEntry();
+ }
+:({WSPACE}+|\\{NEWLINE}) {
+ // A colon followed by space or line continuation ends the rules
+ // and starts a new dependency.
yyextra->newDependency();
}
{WSPACE}+ {
diff --git a/Source/cmDependsCompiler.cxx b/Source/cmDependsCompiler.cxx
index bf599ff..0cc4946 100644
--- a/Source/cmDependsCompiler.cxx
+++ b/Source/cmDependsCompiler.cxx
@@ -4,6 +4,7 @@
#include "cmDependsCompiler.h"
#include <algorithm>
+#include <iterator>
#include <map>
#include <memory>
#include <string>
@@ -111,9 +112,13 @@ bool cmDependsCompiler::CheckDependencies(
// copy depends for each target, except first one, which can be
// moved
for (auto index = entry.rules.size() - 1; index > 0; --index) {
- dependencies[entry.rules[index]] = depends;
+ auto& rule_deps = dependencies[entry.rules[index]];
+ rule_deps.insert(rule_deps.end(), depends.cbegin(),
+ depends.cend());
}
- dependencies[entry.rules.front()] = std::move(depends);
+ auto& rule_deps = dependencies[entry.rules.front()];
+ std::move(depends.cbegin(), depends.cend(),
+ std::back_inserter(rule_deps));
}
} else {
if (format == "msvc"_s) {
diff --git a/Source/cmGccDepfileLexerHelper.cxx b/Source/cmGccDepfileLexerHelper.cxx
index afa8e9b..34c8824 100644
--- a/Source/cmGccDepfileLexerHelper.cxx
+++ b/Source/cmGccDepfileLexerHelper.cxx
@@ -113,6 +113,24 @@ void cmGccDepfileLexerHelper::addToCurrentPath(const char* s)
void cmGccDepfileLexerHelper::sanitizeContent()
{
for (auto it = this->Content.begin(); it != this->Content.end();) {
+ // Remove empty paths and normalize windows paths
+ for (auto pit = it->paths.begin(); pit != it->paths.end();) {
+ if (pit->empty()) {
+ pit = it->paths.erase(pit);
+ } else {
+#if defined(_WIN32)
+ // Unescape the colon following the drive letter.
+ // Some versions of GNU compilers can escape this character.
+ // c\:\path must be transformed to c:\path
+ if (pit->size() >= 3 && std::toupper((*pit)[0]) >= 'A' &&
+ std::toupper((*pit)[0]) <= 'Z' && (*pit)[1] == '\\' &&
+ (*pit)[2] == ':') {
+ pit->erase(1, 1);
+ }
+#endif
+ ++pit;
+ }
+ }
// Remove empty rules
for (auto rit = it->rules.begin(); rit != it->rules.end();) {
if (rit->empty()) {
@@ -121,28 +139,10 @@ void cmGccDepfileLexerHelper::sanitizeContent()
++rit;
}
}
- // Remove the entry if rules are empty
- if (it->rules.empty()) {
+ // Remove the entry if rules are empty or do not have any paths
+ if (it->rules.empty() || it->paths.empty()) {
it = this->Content.erase(it);
} else {
- // Remove empty paths and normalize windows paths
- for (auto pit = it->paths.begin(); pit != it->paths.end();) {
- if (pit->empty()) {
- pit = it->paths.erase(pit);
- } else {
-#if defined(_WIN32)
- // Unescape the colon following the drive letter.
- // Some versions of GNU compilers can escape this character.
- // c\:\path must be transformed to c:\path
- if (pit->size() >= 3 && std::toupper((*pit)[0]) >= 'A' &&
- std::toupper((*pit)[0]) <= 'Z' && (*pit)[1] == '\\' &&
- (*pit)[2] == ':') {
- pit->erase(1, 1);
- }
-#endif
- ++pit;
- }
- }
++it;
}
}
diff --git a/Source/cmTransformDepfile.cxx b/Source/cmTransformDepfile.cxx
index 4032596..81a6507 100644
--- a/Source/cmTransformDepfile.cxx
+++ b/Source/cmTransformDepfile.cxx
@@ -4,7 +4,6 @@
#include <algorithm>
#include <functional>
-#include <memory>
#include <string>
#include <type_traits>
#include <utility>
@@ -95,14 +94,16 @@ void WriteMSBuildAdditionalInputs(cmsys::ofstream& fout,
// Write the format expected by MSBuild CustomBuild AdditionalInputs.
const char* sep = "";
- for (std::string path : content.front().paths) {
- if (!cmSystemTools::FileIsFullPath(path)) {
- path =
- cmSystemTools::CollapseFullPath(path, lg.GetCurrentBinaryDirectory());
+ for (const auto& c : content) {
+ for (std::string path : c.paths) {
+ if (!cmSystemTools::FileIsFullPath(path)) {
+ path = cmSystemTools::CollapseFullPath(path,
+ lg.GetCurrentBinaryDirectory());
+ }
+ std::replace(path.begin(), path.end(), '/', '\\');
+ fout << sep << path;
+ sep = ";";
}
- std::replace(path.begin(), path.end(), '/', '\\');
- fout << sep << path;
- sep = ";";
}
fout << "\n";
}
diff --git a/Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake b/Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake
index e4fdb4a..19c09c8 100644
--- a/Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake
+++ b/Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake
@@ -24,6 +24,13 @@ add_library(toplib STATIC toplib.c)
add_subdirectory(DepfileSubdir)
+add_custom_command(
+ OUTPUT toplib2.c
+ DEPFILE toplib2.c.d
+ COMMAND ${CMAKE_COMMAND} -DOUTFILE=toplib2.c -DINFILE=toplibdep2.txt -DDEPFILE=toplib2.c.d -P "${CMAKE_CURRENT_LIST_DIR}/WriteDepfile2.cmake"
+ )
+add_library(toplib2 STATIC toplib2.c)
+
file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT "
function(check_exists file)
if(NOT EXISTS \"\${file}\")
@@ -43,6 +50,7 @@ set(check_pairs
\"${CMAKE_BINARY_DIR}/topcc.c|${CMAKE_BINARY_DIR}/topccdep.txt\"
\"$<TARGET_FILE:topexe>|${CMAKE_BINARY_DIR}/topexedep.txt\"
\"$<TARGET_FILE:toplib>|${CMAKE_BINARY_DIR}/toplibdep.txt\"
+ \"$<TARGET_FILE:toplib2>|${CMAKE_BINARY_DIR}/toplibdep2.txt\"
\"${CMAKE_BINARY_DIR}/DepfileSubdir/subcc.c|${CMAKE_BINARY_DIR}/DepfileSubdir/subccdep.txt\"
\"$<TARGET_FILE:subexe>|${CMAKE_BINARY_DIR}/DepfileSubdir/subexedep.txt\"
\"$<TARGET_FILE:sublib>|${CMAKE_BINARY_DIR}/DepfileSubdir/sublibdep.txt\"
@@ -53,6 +61,7 @@ if(check_step EQUAL 3)
\"${CMAKE_BINARY_DIR}/step3.timestamp|${CMAKE_BINARY_DIR}/topcc.c\"
\"${CMAKE_BINARY_DIR}/step3.timestamp|$<TARGET_FILE:topexe>\"
\"${CMAKE_BINARY_DIR}/step3.timestamp|$<TARGET_FILE:toplib>\"
+ \"${CMAKE_BINARY_DIR}/step3.timestamp|$<TARGET_FILE:toplib2>\"
\"${CMAKE_BINARY_DIR}/step3.timestamp|${CMAKE_BINARY_DIR}/DepfileSubdir/subcc.c\"
\"${CMAKE_BINARY_DIR}/step3.timestamp|$<TARGET_FILE:subexe>\"
\"${CMAKE_BINARY_DIR}/step3.timestamp|$<TARGET_FILE:sublib>\"
diff --git a/Tests/RunCMake/BuildDepends/CustomCommandDepfile.step1.cmake b/Tests/RunCMake/BuildDepends/CustomCommandDepfile.step1.cmake
index 0dfe78e..a33a03c 100644
--- a/Tests/RunCMake/BuildDepends/CustomCommandDepfile.step1.cmake
+++ b/Tests/RunCMake/BuildDepends/CustomCommandDepfile.step1.cmake
@@ -5,6 +5,7 @@ file(REMOVE "${RunCMake_TEST_BINARY_DIR}/step3.timestamp")
file(TOUCH "${RunCMake_TEST_BINARY_DIR}/topccdep.txt")
file(TOUCH "${RunCMake_TEST_BINARY_DIR}/topexedep.txt")
file(TOUCH "${RunCMake_TEST_BINARY_DIR}/toplibdep.txt")
+file(TOUCH "${RunCMake_TEST_BINARY_DIR}/toplibdep2.txt")
file(TOUCH "${RunCMake_TEST_BINARY_DIR}/DepfileSubdir/subccdep.txt")
file(TOUCH "${RunCMake_TEST_BINARY_DIR}/DepfileSubdir/subexedep.txt")
file(TOUCH "${RunCMake_TEST_BINARY_DIR}/DepfileSubdir/sublibdep.txt")
diff --git a/Tests/RunCMake/BuildDepends/CustomCommandDepfile.step2.cmake b/Tests/RunCMake/BuildDepends/CustomCommandDepfile.step2.cmake
index c711514..ee7df7b 100644
--- a/Tests/RunCMake/BuildDepends/CustomCommandDepfile.step2.cmake
+++ b/Tests/RunCMake/BuildDepends/CustomCommandDepfile.step2.cmake
@@ -1,6 +1,7 @@
file(TOUCH "${RunCMake_TEST_BINARY_DIR}/topccdep.txt")
file(TOUCH "${RunCMake_TEST_BINARY_DIR}/topexedep.txt")
file(TOUCH "${RunCMake_TEST_BINARY_DIR}/toplibdep.txt")
+file(TOUCH "${RunCMake_TEST_BINARY_DIR}/toplibdep2.txt")
file(TOUCH "${RunCMake_TEST_BINARY_DIR}/DepfileSubdir/subccdep.txt")
file(TOUCH "${RunCMake_TEST_BINARY_DIR}/DepfileSubdir/subexedep.txt")
file(TOUCH "${RunCMake_TEST_BINARY_DIR}/DepfileSubdir/sublibdep.txt")
diff --git a/Tests/RunCMake/BuildDepends/WriteDepfile2.cmake b/Tests/RunCMake/BuildDepends/WriteDepfile2.cmake
new file mode 100644
index 0000000..f7898f6
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/WriteDepfile2.cmake
@@ -0,0 +1,8 @@
+file(WRITE "${OUTFILE}" [[int main(void)
+{
+ return 0;
+}
+]])
+string(REPLACE [[ ]] [[\ ]] OUTFILE "${OUTFILE}")
+string(REPLACE [[ ]] [[\ ]] INFILE "${INFILE}")
+file(WRITE "${DEPFILE}" "${OUTFILE}:\n${OUTFILE}: ${INFILE}\n")
diff --git a/Tests/RunCMake/CheckCompilerFlag/NonExistentLanguage-stderr.txt b/Tests/RunCMake/CheckCompilerFlag/NonExistentLanguage-stderr.txt
index 89d0565..99491e8 100644
--- a/Tests/RunCMake/CheckCompilerFlag/NonExistentLanguage-stderr.txt
+++ b/Tests/RunCMake/CheckCompilerFlag/NonExistentLanguage-stderr.txt
@@ -1,2 +1,2 @@
-CMake Error at .*CheckCompilerFlag\.cmake:[0-9]+ \(message\):
+CMake Error at .*CheckFlagCommonConfig\.cmake:[0-9]+ \(message\):
check_compiler_flag: FAKE_LANG: unknown language.
diff --git a/Tests/RunCMake/CheckCompilerFlag/NotEnabledLanguage-stderr.txt b/Tests/RunCMake/CheckCompilerFlag/NotEnabledLanguage-stderr.txt
index 23dd4a1..82c47e3 100644
--- a/Tests/RunCMake/CheckCompilerFlag/NotEnabledLanguage-stderr.txt
+++ b/Tests/RunCMake/CheckCompilerFlag/NotEnabledLanguage-stderr.txt
@@ -1,2 +1,2 @@
-CMake Error at .*CheckCompilerFlag\.cmake:[0-9]+ \(message\):
+CMake Error at .*CheckFlagCommonConfig\.cmake:[0-9]+ \(message\):
check_compiler_flag: C: needs to be enabled before use.
diff --git a/Tests/RunCMake/find_library/FromPATHEnv.cmake b/Tests/RunCMake/find_library/FromPATHEnv.cmake
index c24e640..ba4dd37 100644
--- a/Tests/RunCMake/find_library/FromPATHEnv.cmake
+++ b/Tests/RunCMake/find_library/FromPATHEnv.cmake
@@ -1,6 +1,8 @@
list(APPEND CMAKE_FIND_LIBRARY_PREFIXES lib)
list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES .a)
set(ENV_PATH "$ENV{PATH}")
+set(ENV_CMAKE_PREFIX_PATH "$ENV{CMAKE_PREFIX_PATH}")
+set(ENV{CMAKE_PREFIX_PATH} "")
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib/libcreated.a" "created")
@@ -33,3 +35,4 @@ foreach(path "/does_not_exist" "/lib" "")
endforeach()
set(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH ON)
set(ENV{PATH} "${ENV_PATH}")
+set(ENV{CMAKE_PREFIX_PATH} "${ENV_CMAKE_PREFIX_PATH}")
diff --git a/Tests/RunCMake/find_library/FromPATHEnvDebugVar.cmake b/Tests/RunCMake/find_library/FromPATHEnvDebugVar.cmake
index c24e640..ba4dd37 100644
--- a/Tests/RunCMake/find_library/FromPATHEnvDebugVar.cmake
+++ b/Tests/RunCMake/find_library/FromPATHEnvDebugVar.cmake
@@ -1,6 +1,8 @@
list(APPEND CMAKE_FIND_LIBRARY_PREFIXES lib)
list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES .a)
set(ENV_PATH "$ENV{PATH}")
+set(ENV_CMAKE_PREFIX_PATH "$ENV{CMAKE_PREFIX_PATH}")
+set(ENV{CMAKE_PREFIX_PATH} "")
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib/libcreated.a" "created")
@@ -33,3 +35,4 @@ foreach(path "/does_not_exist" "/lib" "")
endforeach()
set(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH ON)
set(ENV{PATH} "${ENV_PATH}")
+set(ENV{CMAKE_PREFIX_PATH} "${ENV_CMAKE_PREFIX_PATH}")
diff --git a/Tests/RunCMake/find_library/FromPrefixPath.cmake b/Tests/RunCMake/find_library/FromPrefixPath.cmake
index 04763a9..52814e8 100644
--- a/Tests/RunCMake/find_library/FromPrefixPath.cmake
+++ b/Tests/RunCMake/find_library/FromPrefixPath.cmake
@@ -1,7 +1,9 @@
list(APPEND CMAKE_FIND_LIBRARY_PREFIXES lib)
list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES .a)
set(ENV_PATH "$ENV{PATH}")
+set(ENV_CMAKE_PREFIX_PATH "$ENV{CMAKE_PREFIX_PATH}")
set(ENV{PATH} "")
+set(ENV{CMAKE_PREFIX_PATH} "")
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib/libcreated.a" "created")
@@ -22,3 +24,4 @@ foreach(path "/does_not_exist" "/lib" "")
endforeach()
set(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH ON)
set(ENV{PATH} "${ENV_PATH}")
+set(ENV{CMAKE_PREFIX_PATH} "${ENV_CMAKE_PREFIX_PATH}")
diff --git a/Utilities/Scripts/update-expat.bash b/Utilities/Scripts/update-expat.bash
index a052c0e..53449d0 100755
--- a/Utilities/Scripts/update-expat.bash
+++ b/Utilities/Scripts/update-expat.bash
@@ -8,7 +8,7 @@ readonly name="expat"
readonly ownership="Expat Upstream <kwrobot@kitware.com>"
readonly subtree="Utilities/cmexpat"
readonly repo="https://github.com/libexpat/libexpat.git"
-readonly tag="R_2_4_1"
+readonly tag="R_2_4_3"
readonly shortlog=false
readonly paths="
expat/lib/asciitab.h
diff --git a/Utilities/cmexpat/ConfigureChecks.cmake b/Utilities/cmexpat/ConfigureChecks.cmake
index 4da252c..341bab7 100644
--- a/Utilities/cmexpat/ConfigureChecks.cmake
+++ b/Utilities/cmexpat/ConfigureChecks.cmake
@@ -2,6 +2,7 @@ include(CheckCCompilerFlag)
include(CheckCSourceCompiles)
include(CheckIncludeFile)
include(CheckIncludeFiles)
+include(CheckLibraryExists)
include(CheckSymbolExists)
include(TestBigEndian)
diff --git a/Utilities/cmexpat/README.md b/Utilities/cmexpat/README.md
index 251dc8a..6fdd614 100644
--- a/Utilities/cmexpat/README.md
+++ b/Utilities/cmexpat/README.md
@@ -5,7 +5,7 @@
[![Downloads GitHub](https://img.shields.io/github/downloads/libexpat/libexpat/total?label=Downloads%20GitHub)](https://github.com/libexpat/libexpat/releases)
-# Expat, Release 2.4.1
+# Expat, Release 2.4.3
This is Expat, a C library for parsing XML, started by
[James Clark](https://en.wikipedia.org/wiki/James_Clark_%28programmer%29) in 1997.
diff --git a/Utilities/cmexpat/lib/expat.h b/Utilities/cmexpat/lib/expat.h
index b7d6d35..0f021e2 100644
--- a/Utilities/cmexpat/lib/expat.h
+++ b/Utilities/cmexpat/lib/expat.h
@@ -11,7 +11,7 @@
Copyright (c) 2000-2005 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2001-2002 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net>
- Copyright (c) 2016-2021 Sebastian Pipping <sebastian@pipping.org>
+ Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016 Cristian Rodríguez <crrodriguez@opensuse.org>
Copyright (c) 2016 Thomas Beutlich <tc@tbeu.de>
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
@@ -1041,7 +1041,7 @@ XML_SetBillionLaughsAttackProtectionActivationThreshold(
*/
#define XML_MAJOR_VERSION 2
#define XML_MINOR_VERSION 4
-#define XML_MICRO_VERSION 1
+#define XML_MICRO_VERSION 3
#ifdef __cplusplus
}
diff --git a/Utilities/cmexpat/lib/xmlparse.c b/Utilities/cmexpat/lib/xmlparse.c
index 5ba56eae..b2f5fc6 100644
--- a/Utilities/cmexpat/lib/xmlparse.c
+++ b/Utilities/cmexpat/lib/xmlparse.c
@@ -1,4 +1,4 @@
-/* 8539b9040d9d901366a62560a064af7cb99811335784b363abc039c5b0ebc416 (2.4.1+)
+/* 9ca2a2fedc35bcb13ba9a134ba5e173020bc2ff5f5a311abf742cec7da1ff26a (2.4.3+)
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
@@ -13,7 +13,7 @@
Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2005-2009 Steven Solie <ssolie@users.sourceforge.net>
Copyright (c) 2016 Eric Rahm <erahm@mozilla.com>
- Copyright (c) 2016-2021 Sebastian Pipping <sebastian@pipping.org>
+ Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016 Gaurav <g.gupta@samsung.com>
Copyright (c) 2016 Thomas Beutlich <tc@tbeu.de>
Copyright (c) 2016 Gustavo Grieco <gustavo.grieco@imag.fr>
@@ -32,6 +32,7 @@
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2019-2020 Ben Wagner <bungeman@chromium.org>
Copyright (c) 2019 Vadim Zeitlin <vadim@zeitlins.org>
+ Copyright (c) 2021 Dong-hee Na <donghee.na@python.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -54,6 +55,10 @@
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
+#define XML_BUILDING_EXPAT 1
+
+#include <expat_config.h>
+
#if ! defined(_GNU_SOURCE)
# define _GNU_SOURCE 1 /* syscall prototype */
#endif
@@ -84,14 +89,10 @@
# include <errno.h>
#endif
-#define XML_BUILDING_EXPAT 1
-
#ifdef _WIN32
# include "winconfig.h"
#endif
-#include <expat_config.h>
-
#include "ascii.h"
#include "expat.h"
#include "siphash.h"
@@ -3260,13 +3261,38 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
/* get the attributes from the tokenizer */
n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts);
+
+ /* Detect and prevent integer overflow */
+ if (n > INT_MAX - nDefaultAtts) {
+ return XML_ERROR_NO_MEMORY;
+ }
+
if (n + nDefaultAtts > parser->m_attsSize) {
int oldAttsSize = parser->m_attsSize;
ATTRIBUTE *temp;
#ifdef XML_ATTR_INFO
XML_AttrInfo *temp2;
#endif
+
+ /* Detect and prevent integer overflow */
+ if ((nDefaultAtts > INT_MAX - INIT_ATTS_SIZE)
+ || (n > INT_MAX - (nDefaultAtts + INIT_ATTS_SIZE))) {
+ return XML_ERROR_NO_MEMORY;
+ }
+
parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
+
+ /* Detect and prevent integer overflow.
+ * The preprocessor guard addresses the "always false" warning
+ * from -Wtype-limits on platforms where
+ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
+#if UINT_MAX >= SIZE_MAX
+ if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(ATTRIBUTE)) {
+ parser->m_attsSize = oldAttsSize;
+ return XML_ERROR_NO_MEMORY;
+ }
+#endif
+
temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts,
parser->m_attsSize * sizeof(ATTRIBUTE));
if (temp == NULL) {
@@ -3275,6 +3301,17 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
}
parser->m_atts = temp;
#ifdef XML_ATTR_INFO
+ /* Detect and prevent integer overflow.
+ * The preprocessor guard addresses the "always false" warning
+ * from -Wtype-limits on platforms where
+ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
+# if UINT_MAX >= SIZE_MAX
+ if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(XML_AttrInfo)) {
+ parser->m_attsSize = oldAttsSize;
+ return XML_ERROR_NO_MEMORY;
+ }
+# endif
+
temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo,
parser->m_attsSize * sizeof(XML_AttrInfo));
if (temp2 == NULL) {
@@ -3413,7 +3450,13 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
if (nPrefixes) {
int j; /* hash table index */
unsigned long version = parser->m_nsAttsVersion;
- int nsAttsSize = (int)1 << parser->m_nsAttsPower;
+
+ /* Detect and prevent invalid shift */
+ if (parser->m_nsAttsPower >= sizeof(unsigned int) * 8 /* bits per byte */) {
+ return XML_ERROR_NO_MEMORY;
+ }
+
+ unsigned int nsAttsSize = 1u << parser->m_nsAttsPower;
unsigned char oldNsAttsPower = parser->m_nsAttsPower;
/* size of hash table must be at least 2 * (# of prefixed attributes) */
if ((nPrefixes << 1)
@@ -3424,7 +3467,28 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
;
if (parser->m_nsAttsPower < 3)
parser->m_nsAttsPower = 3;
- nsAttsSize = (int)1 << parser->m_nsAttsPower;
+
+ /* Detect and prevent invalid shift */
+ if (parser->m_nsAttsPower >= sizeof(nsAttsSize) * 8 /* bits per byte */) {
+ /* Restore actual size of memory in m_nsAtts */
+ parser->m_nsAttsPower = oldNsAttsPower;
+ return XML_ERROR_NO_MEMORY;
+ }
+
+ nsAttsSize = 1u << parser->m_nsAttsPower;
+
+ /* Detect and prevent integer overflow.
+ * The preprocessor guard addresses the "always false" warning
+ * from -Wtype-limits on platforms where
+ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
+#if UINT_MAX >= SIZE_MAX
+ if (nsAttsSize > (size_t)(-1) / sizeof(NS_ATT)) {
+ /* Restore actual size of memory in m_nsAtts */
+ parser->m_nsAttsPower = oldNsAttsPower;
+ return XML_ERROR_NO_MEMORY;
+ }
+#endif
+
temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts,
nsAttsSize * sizeof(NS_ATT));
if (! temp) {
@@ -3582,9 +3646,31 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
tagNamePtr->prefixLen = prefixLen;
for (i = 0; localPart[i++];)
; /* i includes null terminator */
+
+ /* Detect and prevent integer overflow */
+ if (binding->uriLen > INT_MAX - prefixLen
+ || i > INT_MAX - (binding->uriLen + prefixLen)) {
+ return XML_ERROR_NO_MEMORY;
+ }
+
n = i + binding->uriLen + prefixLen;
if (n > binding->uriAlloc) {
TAG *p;
+
+ /* Detect and prevent integer overflow */
+ if (n > INT_MAX - EXPAND_SPARE) {
+ return XML_ERROR_NO_MEMORY;
+ }
+ /* Detect and prevent integer overflow.
+ * The preprocessor guard addresses the "always false" warning
+ * from -Wtype-limits on platforms where
+ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
+#if UINT_MAX >= SIZE_MAX
+ if ((unsigned)(n + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
+ return XML_ERROR_NO_MEMORY;
+ }
+#endif
+
uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char));
if (! uri)
return XML_ERROR_NO_MEMORY;
@@ -3680,6 +3766,21 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
if (parser->m_freeBindingList) {
b = parser->m_freeBindingList;
if (len > b->uriAlloc) {
+ /* Detect and prevent integer overflow */
+ if (len > INT_MAX - EXPAND_SPARE) {
+ return XML_ERROR_NO_MEMORY;
+ }
+
+ /* Detect and prevent integer overflow.
+ * The preprocessor guard addresses the "always false" warning
+ * from -Wtype-limits on platforms where
+ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
+#if UINT_MAX >= SIZE_MAX
+ if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
+ return XML_ERROR_NO_MEMORY;
+ }
+#endif
+
XML_Char *temp = (XML_Char *)REALLOC(
parser, b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
if (temp == NULL)
@@ -3692,6 +3793,21 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
b = (BINDING *)MALLOC(parser, sizeof(BINDING));
if (! b)
return XML_ERROR_NO_MEMORY;
+
+ /* Detect and prevent integer overflow */
+ if (len > INT_MAX - EXPAND_SPARE) {
+ return XML_ERROR_NO_MEMORY;
+ }
+ /* Detect and prevent integer overflow.
+ * The preprocessor guard addresses the "always false" warning
+ * from -Wtype-limits on platforms where
+ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
+#if UINT_MAX >= SIZE_MAX
+ if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
+ return XML_ERROR_NO_MEMORY;
+ }
+#endif
+
b->uri
= (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE));
if (! b->uri) {
@@ -5018,6 +5134,11 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
if (parser->m_prologState.level >= parser->m_groupSize) {
if (parser->m_groupSize) {
{
+ /* Detect and prevent integer overflow */
+ if (parser->m_groupSize > (unsigned int)(-1) / 2u) {
+ return XML_ERROR_NO_MEMORY;
+ }
+
char *const new_connector = (char *)REALLOC(
parser, parser->m_groupConnector, parser->m_groupSize *= 2);
if (new_connector == NULL) {
@@ -5028,6 +5149,16 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
}
if (dtd->scaffIndex) {
+ /* Detect and prevent integer overflow.
+ * The preprocessor guard addresses the "always false" warning
+ * from -Wtype-limits on platforms where
+ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
+#if UINT_MAX >= SIZE_MAX
+ if (parser->m_groupSize > (size_t)(-1) / sizeof(int)) {
+ return XML_ERROR_NO_MEMORY;
+ }
+#endif
+
int *const new_scaff_index = (int *)REALLOC(
parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int));
if (new_scaff_index == NULL)
@@ -6098,7 +6229,24 @@ defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
}
} else {
DEFAULT_ATTRIBUTE *temp;
+
+ /* Detect and prevent integer overflow */
+ if (type->allocDefaultAtts > INT_MAX / 2) {
+ return 0;
+ }
+
int count = type->allocDefaultAtts * 2;
+
+ /* Detect and prevent integer overflow.
+ * The preprocessor guard addresses the "always false" warning
+ * from -Wtype-limits on platforms where
+ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
+#if UINT_MAX >= SIZE_MAX
+ if ((unsigned)count > (size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE)) {
+ return 0;
+ }
+#endif
+
temp = (DEFAULT_ATTRIBUTE *)REALLOC(parser, type->defaultAtts,
(count * sizeof(DEFAULT_ATTRIBUTE)));
if (temp == NULL)
@@ -6749,8 +6897,20 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
/* check for overflow (table is half full) */
if (table->used >> (table->power - 1)) {
unsigned char newPower = table->power + 1;
+
+ /* Detect and prevent invalid shift */
+ if (newPower >= sizeof(unsigned long) * 8 /* bits per byte */) {
+ return NULL;
+ }
+
size_t newSize = (size_t)1 << newPower;
unsigned long newMask = (unsigned long)newSize - 1;
+
+ /* Detect and prevent integer overflow */
+ if (newSize > (size_t)(-1) / sizeof(NAMED *)) {
+ return NULL;
+ }
+
size_t tsize = newSize * sizeof(NAMED *);
NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
if (! newV)
@@ -7100,6 +7260,20 @@ nextScaffoldPart(XML_Parser parser) {
if (dtd->scaffCount >= dtd->scaffSize) {
CONTENT_SCAFFOLD *temp;
if (dtd->scaffold) {
+ /* Detect and prevent integer overflow */
+ if (dtd->scaffSize > UINT_MAX / 2u) {
+ return -1;
+ }
+ /* Detect and prevent integer overflow.
+ * The preprocessor guard addresses the "always false" warning
+ * from -Wtype-limits on platforms where
+ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
+#if UINT_MAX >= SIZE_MAX
+ if (dtd->scaffSize > (size_t)(-1) / 2u / sizeof(CONTENT_SCAFFOLD)) {
+ return -1;
+ }
+#endif
+
temp = (CONTENT_SCAFFOLD *)REALLOC(
parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
if (temp == NULL)
@@ -7169,8 +7343,26 @@ build_model(XML_Parser parser) {
XML_Content *ret;
XML_Content *cpos;
XML_Char *str;
- int allocsize = (dtd->scaffCount * sizeof(XML_Content)
- + (dtd->contentStringLen * sizeof(XML_Char)));
+
+ /* Detect and prevent integer overflow.
+ * The preprocessor guard addresses the "always false" warning
+ * from -Wtype-limits on platforms where
+ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
+#if UINT_MAX >= SIZE_MAX
+ if (dtd->scaffCount > (size_t)(-1) / sizeof(XML_Content)) {
+ return NULL;
+ }
+ if (dtd->contentStringLen > (size_t)(-1) / sizeof(XML_Char)) {
+ return NULL;
+ }
+#endif
+ if (dtd->scaffCount * sizeof(XML_Content)
+ > (size_t)(-1) - dtd->contentStringLen * sizeof(XML_Char)) {
+ return NULL;
+ }
+
+ const size_t allocsize = (dtd->scaffCount * sizeof(XML_Content)
+ + (dtd->contentStringLen * sizeof(XML_Char)));
ret = (XML_Content *)MALLOC(parser, allocsize);
if (! ret)
diff --git a/Utilities/cmexpat/lib/xmlrole.c b/Utilities/cmexpat/lib/xmlrole.c
index 08173b0..77746ee 100644
--- a/Utilities/cmexpat/lib/xmlrole.c
+++ b/Utilities/cmexpat/lib/xmlrole.c
@@ -15,6 +15,7 @@
Copyright (c) 2016-2021 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
+ Copyright (c) 2021 Dong-hee Na <donghee.na@python.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -37,14 +38,14 @@
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
+#include <expat_config.h>
+
#include <stddef.h>
#ifdef _WIN32
# include "winconfig.h"
#endif
-#include <expat_config.h>
-
#include "expat_external.h"
#include "internal.h"
#include "xmlrole.h"
diff --git a/Utilities/cmexpat/lib/xmltok.c b/Utilities/cmexpat/lib/xmltok.c
index f2b6b40..502ca1a 100644
--- a/Utilities/cmexpat/lib/xmltok.c
+++ b/Utilities/cmexpat/lib/xmltok.c
@@ -20,6 +20,7 @@
Copyright (c) 2017 Benbuck Nason <bnason@netflix.com>
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
+ Copyright (c) 2021 Dong-hee Na <donghee.na@python.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -42,6 +43,8 @@
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
+#include <expat_config.h>
+
#include <stddef.h>
#include <string.h> /* memcpy */
#include <stdbool.h>
@@ -50,8 +53,6 @@
# include "winconfig.h"
#endif
-#include <expat_config.h>
-
#include "expat_external.h"
#include "internal.h"
#include "xmltok.h"
diff --git a/Utilities/cmexpat/lib/xmltok_ns.c b/Utilities/cmexpat/lib/xmltok_ns.c
index 5fd8392..fbdd3e3 100644
--- a/Utilities/cmexpat/lib/xmltok_ns.c
+++ b/Utilities/cmexpat/lib/xmltok_ns.c
@@ -11,7 +11,7 @@
Copyright (c) 2002 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net>
- Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
+ Copyright (c) 2017-2021 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -93,7 +93,7 @@ NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr,
static const ENCODING *
NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) {
# define ENCODING_MAX 128
- char buf[ENCODING_MAX];
+ char buf[ENCODING_MAX] = "";
char *p = buf;
int i;
XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1);