Merge topic 'automoc-case-change'

318ec07560 automoc: Remove existing output file before invoking moc

Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: buildbot <buildbot@kitware.com>
Merge-request: !7985
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index a2b3ec3..cd3f0a0 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -325,6 +325,26 @@
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
+t:linux-clang-cxx-modules-ninja:
+    extends:
+        - .clang_cxx_modules_ninja
+        - .cmake_test_linux_release
+        - .linux_x86_64_tags
+        - .run_dependent
+        - .needs_centos6_x86_64
+    variables:
+        CMAKE_CI_JOB_NIGHTLY: "true"
+
+t:linux-clang-cxx-modules-ninja-multi:
+    extends:
+        - .clang_cxx_modules_ninja_multi
+        - .cmake_test_linux_release
+        - .linux_x86_64_tags
+        - .run_dependent
+        - .needs_centos6_x86_64
+    variables:
+        CMAKE_CI_JOB_NIGHTLY: "true"
+
 b:fedora37-ninja:
     extends:
         - .fedora37_ninja
diff --git a/.gitlab/ci/configure_linux_clang_cxx_modules_ninja.cmake b/.gitlab/ci/configure_linux_clang_cxx_modules_ninja.cmake
new file mode 100644
index 0000000..43bccdb
--- /dev/null
+++ b/.gitlab/ci/configure_linux_clang_cxx_modules_ninja.cmake
@@ -0,0 +1,4 @@
+set(CMake_TEST_MODULE_COMPILATION "named,partitions,internal_partitions,export_bmi,install_bmi,shared" CACHE STRING "")
+set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_clang.cmake" CACHE STRING "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_linux_clang_cxx_modules_ninja_multi.cmake b/.gitlab/ci/configure_linux_clang_cxx_modules_ninja_multi.cmake
new file mode 100644
index 0000000..43bccdb
--- /dev/null
+++ b/.gitlab/ci/configure_linux_clang_cxx_modules_ninja_multi.cmake
@@ -0,0 +1,4 @@
+set(CMake_TEST_MODULE_COMPILATION "named,partitions,internal_partitions,export_bmi,install_bmi,shared" CACHE STRING "")
+set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_clang.cmake" CACHE STRING "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/cxx_modules_rules_clang.cmake b/.gitlab/ci/cxx_modules_rules_clang.cmake
new file mode 100644
index 0000000..9d75880
--- /dev/null
+++ b/.gitlab/ci/cxx_modules_rules_clang.cmake
@@ -0,0 +1,16 @@
+set(CMake_TEST_CXXModules_UUID "a246741c-d067-4019-a8fb-3d16b0c9d1d3")
+
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
+string(CONCAT CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE
+  "${CMAKE_CXX_COMPILER_CLANG_SCAN_DEPS}"
+  " -format=p1689 --p1689-targeted-file-name=<SOURCE> --p1689-targeted-output=<OBJECT> --"
+  " <DEFINES> <INCLUDES> <FLAGS> -x c++ <SOURCE>"
+  " > <DYNDEP_FILE>")
+# No support for `-MF` discovered dependencies in `clang-scan-deps`.
+set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_DEPFILE_FORMAT "none")
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FORMAT "clang")
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG "@<MODULE_MAP_FILE>")
+
+# Default to C++ extensions being off. Clang's modules support have trouble
+# with extensions right now.
+set(CMAKE_CXX_EXTENSIONS OFF)
diff --git a/.gitlab/ci/docker/clang_cxx_modules/Dockerfile b/.gitlab/ci/docker/clang_cxx_modules/Dockerfile
new file mode 100644
index 0000000..4e58125
--- /dev/null
+++ b/.gitlab/ci/docker/clang_cxx_modules/Dockerfile
@@ -0,0 +1,13 @@
+FROM fedora:37
+MAINTAINER Ben Boeckel <ben.boeckel@kitware.com>
+
+# Install build dependencies for packages.
+COPY install_deps.sh /root/install_deps.sh
+RUN sh /root/install_deps.sh
+
+COPY install_llvm.sh /root/install_llvm.sh
+RUN sh /root/install_llvm.sh
+
+# Install build dependencies for CMake's CI.
+COPY install_cmake_deps.sh /root/install_cmake_deps.sh
+RUN sh /root/install_cmake_deps.sh
diff --git a/.gitlab/ci/docker/clang_cxx_modules/install_cmake_deps.sh b/.gitlab/ci/docker/clang_cxx_modules/install_cmake_deps.sh
new file mode 100755
index 0000000..465e125
--- /dev/null
+++ b/.gitlab/ci/docker/clang_cxx_modules/install_cmake_deps.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+set -e
+
+dnf install -y --setopt=install_weak_deps=False \
+    file git-core
+dnf clean all
diff --git a/.gitlab/ci/docker/clang_cxx_modules/install_deps.sh b/.gitlab/ci/docker/clang_cxx_modules/install_deps.sh
new file mode 100755
index 0000000..c1957c3
--- /dev/null
+++ b/.gitlab/ci/docker/clang_cxx_modules/install_deps.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+set -e
+
+dnf install -y --setopt=install_weak_deps=False \
+    gcc-c++ cmake ninja-build
+dnf clean all
diff --git a/.gitlab/ci/docker/clang_cxx_modules/install_llvm.sh b/.gitlab/ci/docker/clang_cxx_modules/install_llvm.sh
new file mode 100755
index 0000000..09d0106
--- /dev/null
+++ b/.gitlab/ci/docker/clang_cxx_modules/install_llvm.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+set -e
+
+readonly revision="p1689r5-cmake-ci-20221201" # ae3b5489585b60a2b7f090ebb9e1e8729b811253
+readonly tarball="https://github.com/mathstuf/llvm-project/archive/$revision.tar.gz"
+
+readonly workdir="$HOME/llvm"
+readonly srcdir="$workdir/llvm"
+readonly builddir="$workdir/build"
+
+mkdir -p "$workdir"
+cd "$workdir"
+curl -L "$tarball" > "llvm-$revision.tar.gz"
+tar xf "llvm-$revision.tar.gz"
+mv "llvm-project-$revision" "$srcdir"
+mkdir -p "$builddir"
+cd "$builddir"
+cmake -GNinja \
+    -DCMAKE_BUILD_TYPE=Release \
+    -DBUILD_SHARED_LIBS=ON \
+    -DLLVM_ENABLE_BINDINGS=OFF \
+    -DLLVM_INCLUDE_BENCHMARKS=OFF \
+    -DLLVM_INCLUDE_DOCS=OFF \
+    -DLLVM_INCLUDE_EXAMPLES=OFF \
+    -DLLVM_INCLUDE_RUNTIMES=OFF \
+    -DLLVM_INCLUDE_TESTS=OFF \
+    -DLLVM_INCLUDE_UTILS=OFF \
+    -DLLVM_TARGETS_TO_BUILD=X86 \
+    -DLLVM_TOOL_CLANG_BUILD=ON \
+    -DLLVM_USE_SYMLINKS=ON \
+    "-DLLVM_EXTERNAL_CLANG_SOURCE_DIR=$srcdir/clang" \
+    -DLLVM_PARALLEL_LINK_JOBS=1 \
+    -DCLANG_BUILD_TOOLS=ON \
+    "-DCMAKE_INSTALL_PREFIX=/opt/llvm-p1689" \
+    "$srcdir/llvm"
+ninja
+ninja install/strip
+rm -rf "$workdir"
diff --git a/.gitlab/ci/env_nvhpc_ninja.sh b/.gitlab/ci/env_nvhpc_ninja.sh
index 687403d..bf465d2 100644
--- a/.gitlab/ci/env_nvhpc_ninja.sh
+++ b/.gitlab/ci/env_nvhpc_ninja.sh
@@ -3,3 +3,7 @@
 export FC=nvfortran
 export CUDACXX=nvcc
 export CUDAHOSTCXX=nvc++
+# FIXME(#24225): /opt/nvidia/hpc_sdk/Linux_x86_64/22.9/compilers/bin/nvcc
+# selects a CUDA version 10.2 with host driver versions > 520.
+# Manually select the preferred nvcc version.
+export PATH=/opt/nvidia/hpc_sdk/Linux_x86_64/22.9/cuda/11.7/bin:$PATH
diff --git a/.gitlab/ci/post_build.sh b/.gitlab/ci/post_build.sh
new file mode 100755
index 0000000..0edd9f6
--- /dev/null
+++ b/.gitlab/ci/post_build.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+set -e
+
+quietly() {
+  readonly log="/tmp/quietly-$RANDOM.log"
+  if ! "$@" >"$log" 2>&1; then
+    ret=$?
+    cat "$log"
+    rm -f "$log"
+    exit $ret
+  fi
+  rm -f "$log"
+}
+
+if test -r ".gitlab/ci/post_build_${CMAKE_CONFIGURATION}.sh"; then
+  source ".gitlab/ci/post_build_${CMAKE_CONFIGURATION}.sh"
+fi
diff --git a/.gitlab/ci/pre_build.sh b/.gitlab/ci/pre_build.sh
new file mode 100755
index 0000000..7ff6a69
--- /dev/null
+++ b/.gitlab/ci/pre_build.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+set -e
+
+quietly() {
+  readonly log="/tmp/quietly-$RANDOM.log"
+  if ! "$@" >"$log" 2>&1; then
+    ret=$?
+    cat "$log"
+    rm -f "$log"
+    exit $ret
+  fi
+  rm -f "$log"
+}
+
+if test -r ".gitlab/ci/pre_build_${CMAKE_CONFIGURATION}.sh"; then
+  source ".gitlab/ci/pre_build_${CMAKE_CONFIGURATION}.sh"
+fi
diff --git a/.gitlab/ci/env_fedora37_tidy.sh b/.gitlab/ci/pre_build_fedora37_tidy.sh
similarity index 75%
rename from .gitlab/ci/env_fedora37_tidy.sh
rename to .gitlab/ci/pre_build_fedora37_tidy.sh
index f9f08a3..7580ef1 100644
--- a/.gitlab/ci/env_fedora37_tidy.sh
+++ b/.gitlab/ci/pre_build_fedora37_tidy.sh
@@ -1,7 +1,9 @@
 cmake \
+  -G Ninja \
   -S Utilities/ClangTidyModule \
   -B Utilities/ClangTidyModule/build \
   -DCMAKE_BUILD_TYPE=Release \
-  -DRUN_TESTS=ON
+  -DRUN_TESTS=ON \
+  -DCMAKE_CXX_COMPILER_LAUNCHER=sccache
 cmake --build Utilities/ClangTidyModule/build
 ctest --test-dir Utilities/ClangTidyModule/build --output-on-failure
diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml
index decf1b1..637df82 100644
--- a/.gitlab/os-linux.yml
+++ b/.gitlab/os-linux.yml
@@ -372,6 +372,28 @@
         CMAKE_CONFIGURATION: linux_gcc_cxx_modules_ninja_multi
         CMAKE_GENERATOR: "Ninja Multi-Config"
 
+.clang_cxx_modules_x86_64:
+    image: "kitware/cmake:ci-clang_cxx_modules-x86_64-2022-12-02"
+
+    variables:
+        GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
+        CMAKE_ARCH: x86_64
+        CC: "/opt/llvm-p1689/bin/clang"
+        CXX: "/opt/llvm-p1689/bin/clang++"
+
+.clang_cxx_modules_ninja:
+    extends: .clang_cxx_modules_x86_64
+
+    variables:
+        CMAKE_CONFIGURATION: linux_clang_cxx_modules_ninja
+
+.clang_cxx_modules_ninja_multi:
+    extends: .clang_cxx_modules_x86_64
+
+    variables:
+        CMAKE_CONFIGURATION: linux_clang_cxx_modules_ninja_multi
+        CMAKE_GENERATOR: "Ninja Multi-Config"
+
 ## Tags
 
 .linux_x86_64_tags:
@@ -465,8 +487,10 @@
         - .gitlab/ci/sccache.sh
         - sccache --start-server
         - sccache --show-stats
+        - .gitlab/ci/pre_build.sh
         - "$LAUNCHER ctest -VV -S .gitlab/ci/ctest_configure.cmake"
         - "$LAUNCHER ctest -VV -S .gitlab/ci/ctest_build.cmake"
+        - .gitlab/ci/post_build.sh
         - sccache --show-stats
 
     interruptible: true
diff --git a/Help/dev/experimental.rst b/Help/dev/experimental.rst
index 794a686..fbbad30 100644
--- a/Help/dev/experimental.rst
+++ b/Help/dev/experimental.rst
@@ -102,9 +102,9 @@
   set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG
     "${compiler_flags_for_module_map} -fmodule-mapper=<MODULE_MAP_FILE>")
 
-Currently, the only supported formats are ``gcc`` and ``msvc``.  The ``gcc``
-format is described in the GCC documentation, but the relevant section for the
-purposes of CMake is:
+Currently, the only supported formats are, ``clang``, ``gcc``, and ``msvc``.
+The ``gcc`` format is described in the GCC documentation, but the relevant
+section for the purposes of CMake is:
 
     A mapping file consisting of space-separated module-name, filename
     pairs, one per line.  Only the mappings for the direct imports and any
@@ -119,6 +119,9 @@
 any module interfaces properly as well as find any required files to satisfy
 ``import`` statements as required for Microsoft's Visual Studio toolchains.
 
+Similarly, the ``clang`` format is a response file containing flags using
+Clang's module flags.
+
 .. _`D1483r1`: https://mathstuf.fedorapeople.org/fortran-modules/fortran-modules.html
 .. _`P1689r5`: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1689r5.html
 .. _`cxx-modules-sandbox`: https://github.com/mathstuf/cxx-modules-sandbox
diff --git a/Modules/CheckSymbolExists.cmake b/Modules/CheckSymbolExists.cmake
index 0d44d56..722d50f 100644
--- a/Modules/CheckSymbolExists.cmake
+++ b/Modules/CheckSymbolExists.cmake
@@ -136,7 +136,7 @@
   ${_CSE_CHECK_NON_MACRO}")
     endif()
     string(APPEND _CSE_SOURCE "
-}")
+}\n")
     unset(_CSE_CHECK_NON_MACRO)
 
     if(NOT CMAKE_REQUIRED_QUIET)
diff --git a/Modules/Compiler/Clang-FindBinUtils.cmake b/Modules/Compiler/Clang-FindBinUtils.cmake
index 125ae78..daf0371 100644
--- a/Modules/Compiler/Clang-FindBinUtils.cmake
+++ b/Modules/Compiler/Clang-FindBinUtils.cmake
@@ -43,3 +43,14 @@
     DOC "Generate index for LLVM archive"
 )
 mark_as_advanced(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_RANLIB)
+
+# clang-scan-deps
+find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_CLANG_SCAN_DEPS NAMES
+    "${_CMAKE_TOOLCHAIN_PREFIX}clang-scan-deps-${__version_x_y}"
+    "${_CMAKE_TOOLCHAIN_PREFIX}clang-scan-deps-${__version_x}"
+    "${_CMAKE_TOOLCHAIN_PREFIX}clang-scan-deps"
+    HINTS ${__clang_hints}
+    NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH
+    DOC "`clang-scan-deps` dependency scanner"
+)
+mark_as_advanced(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_CLANG_SCAN_DEPS)
diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake
index 80554d0..c9f1a09 100644
--- a/Modules/FetchContent.cmake
+++ b/Modules/FetchContent.cmake
@@ -1425,6 +1425,9 @@
 
   set(options
       QUIET
+      # SYSTEM has no meaning for ExternalProject, it is only used by us in
+      # FetchContent_MakeAvailable(). We need to parse and discard it here.
+      SYSTEM
   )
   set(oneValueArgs
       SUBBUILD_DIR
diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake
index f66ffcf..78b1919 100644
--- a/Modules/FindOpenSSL.cmake
+++ b/Modules/FindOpenSSL.cmake
@@ -112,11 +112,31 @@
 #]=======================================================================]
 
 macro(_OpenSSL_test_and_find_dependencies ssl_library crypto_library)
+  unset(_OpenSSL_extra_static_deps)
   if((CMAKE_SYSTEM_NAME STREQUAL "Linux") AND
      (("${ssl_library}" MATCHES "\\${CMAKE_STATIC_LIBRARY_SUFFIX}$") OR
       ("${crypto_library}" MATCHES "\\${CMAKE_STATIC_LIBRARY_SUFFIX}$")))
     set(_OpenSSL_has_dependencies TRUE)
-    find_package(Threads)
+    unset(_OpenSSL_has_dependency_zlib)
+    if(_OPENSSL_LIBRARIES)
+      unset(_OpenSSL_has_dependency_dl)
+      foreach(_OPENSSL_DEP_LIB IN LISTS _OPENSSL_LIBRARIES)
+        if (_OPENSSL_DEP_LIB STREQUAL "ssl" OR _OPENSSL_DEP_LIB STREQUAL "crypto")
+          # ignoring: these are the targets
+        elseif(_OPENSSL_DEP_LIB STREQUAL CMAKE_DL_LIBS)
+          set(_OpenSSL_has_dependency_dl TRUE)
+        elseif(_OPENSSL_DEP_LIB STREQUAL "z")
+          find_package(ZLIB)
+          set(_OpenSSL_has_dependency_zlib TRUE)
+        else()
+          list(APPEND _OpenSSL_extra_static_deps "${_OPENSSL_DEP_LIB}")
+        endif()
+      endforeach()
+      unset(_OPENSSL_DEP_LIB)
+    else()
+      set(_OpenSSL_has_dependency_dl TRUE)
+      find_package(Threads)
+    endif()
   else()
     set(_OpenSSL_has_dependencies FALSE)
   endif()
@@ -126,14 +146,25 @@
   if(CMAKE_THREAD_LIBS_INIT)
     list(APPEND ${libraries_var} ${CMAKE_THREAD_LIBS_INIT})
   endif()
-  list(APPEND ${libraries_var} ${CMAKE_DL_LIBS})
+  if(_OpenSSL_has_dependency_zlib)
+    list(APPEND ${libraries_var} ${ZLIB_LIBRARY})
+  endif()
+  if(_OpenSSL_has_dependency_dl)
+    list(APPEND ${libraries_var} ${CMAKE_DL_LIBS})
+  endif()
+  list(APPEND ${libraries_var} ${_OpenSSL_extra_static_deps})
   set(${libraries_var} ${${libraries_var}} PARENT_SCOPE)
 endfunction()
 
 function(_OpenSSL_target_add_dependencies target)
   if(_OpenSSL_has_dependencies)
-    set_property( TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES Threads::Threads )
-    set_property( TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${CMAKE_DL_LIBS} )
+    set_property( TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES Threads::Threads ${_OpenSSL_extra_static_deps})
+    if(_OpenSSL_has_dependency_dl)
+      set_property( TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${CMAKE_DL_LIBS} )
+    endif()
+    if(_OpenSSL_has_dependency_zlib)
+      set_property( TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES ZLIB::ZLIB )
+    endif()
   endif()
   if(WIN32 AND OPENSSL_USE_STATIC_LIBS)
     if(WINCE)
@@ -719,3 +750,6 @@
 
 unset(_OPENSSL_FIND_PATH_SUFFIX)
 unset(_OPENSSL_NAME_POSTFIX)
+unset(_OpenSSL_extra_static_deps)
+unset(_OpenSSL_has_dependency_dl)
+unset(_OpenSSL_has_dependency_zlib)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index e358efa..f9a8eb1 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 25)
-set(CMake_VERSION_PATCH 20221204)
+set(CMake_VERSION_PATCH 20221206)
 #set(CMake_VERSION_RC 0)
 set(CMake_VERSION_IS_DIRTY 0)
 
diff --git a/Source/cmCxxModuleMapper.cxx b/Source/cmCxxModuleMapper.cxx
index 84691c9..ca4ffdf 100644
--- a/Source/cmCxxModuleMapper.cxx
+++ b/Source/cmCxxModuleMapper.cxx
@@ -28,6 +28,38 @@
 
 namespace {
 
+std::string CxxModuleMapContentClang(CxxModuleLocations const& loc,
+                                     cmScanDepInfo const& obj)
+{
+  std::stringstream mm;
+
+  // Clang's command line only supports a single output. If more than one is
+  // expected, we cannot make a useful module map file.
+  if (obj.Provides.size() > 1) {
+    return {};
+  }
+
+  // A series of flags which tell the compiler where to look for modules.
+
+  for (auto const& p : obj.Provides) {
+    if (auto bmi_loc = loc.BmiGeneratorPathForModule(p.LogicalName)) {
+      // Force the TU to be considered a C++ module source file regardless of
+      // extension.
+      mm << "-x c++-module\n";
+
+      mm << "-fsave-std-c++-module-file=" << *bmi_loc << '\n';
+      break;
+    }
+  }
+  for (auto const& r : obj.Requires) {
+    if (auto bmi_loc = loc.BmiGeneratorPathForModule(r.LogicalName)) {
+      mm << "-fmodule-file=" << *bmi_loc << '\n';
+    }
+  }
+
+  return mm.str();
+}
+
 std::string CxxModuleMapContentGcc(CxxModuleLocations const& loc,
                                    cmScanDepInfo const& obj)
 {
@@ -179,6 +211,8 @@
 {
   if (format) {
     switch (*format) {
+      case CxxModuleMapFormat::Clang:
+        return ".pcm"_s;
       case CxxModuleMapFormat::Gcc:
         return ".gcm"_s;
       case CxxModuleMapFormat::Msvc:
@@ -297,6 +331,8 @@
                                 CxxModuleUsage const& usages)
 {
   switch (format) {
+    case CxxModuleMapFormat::Clang:
+      return CxxModuleMapContentClang(loc, obj);
     case CxxModuleMapFormat::Gcc:
       return CxxModuleMapContentGcc(loc, obj);
     case CxxModuleMapFormat::Msvc:
diff --git a/Source/cmCxxModuleMapper.h b/Source/cmCxxModuleMapper.h
index 8526a07..9271978 100644
--- a/Source/cmCxxModuleMapper.h
+++ b/Source/cmCxxModuleMapper.h
@@ -17,6 +17,7 @@
 
 enum class CxxModuleMapFormat
 {
+  Clang,
   Gcc,
   Msvc,
 };
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index c80cdb9..2571159 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -4651,7 +4651,8 @@
 std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
   std::string const& config, std::string const& language) const
 {
-  ConfigAndLanguage cacheKey(config, language);
+  ConfigAndLanguage cacheKey(
+    config, cmStrCat(language, this->IsDeviceLink() ? "-device" : ""));
   {
     auto it = this->LinkOptionsCache.find(cacheKey);
     if (it != this->LinkOptionsCache.end()) {
@@ -4937,7 +4938,8 @@
 std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDirectories(
   std::string const& config, std::string const& language) const
 {
-  ConfigAndLanguage cacheKey(config, language);
+  ConfigAndLanguage cacheKey(
+    config, cmStrCat(language, this->IsDeviceLink() ? "-device" : ""));
   {
     auto it = this->LinkDirectoriesCache.find(cacheKey);
     if (it != this->LinkDirectoriesCache.end()) {
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 4500f33..f7753da 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -2567,6 +2567,8 @@
   cm::optional<CxxModuleMapFormat> modmap_fmt;
   if (arg_modmapfmt.empty()) {
     // nothing to do.
+  } else if (arg_modmapfmt == "clang") {
+    modmap_fmt = CxxModuleMapFormat::Clang;
   } else if (arg_modmapfmt == "gcc") {
     modmap_fmt = CxxModuleMapFormat::Gcc;
   } else if (arg_modmapfmt == "msvc") {
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 85a6fc2..3912632 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -542,9 +542,12 @@
   // Scanning always uses a depfile for preprocessor dependencies.
   if (deptype == "msvc"_s) {
     rule.DepType = deptype;
-    rule.DepFile = "";
+    rule.DepFile.clear();
+  } else if (deptype == "none"_s) {
+    rule.DepType.clear(); // no deps= for multiple outputs
+    rule.DepFile.clear();
   } else {
-    rule.DepType = ""; // no deps= for multiple outputs
+    rule.DepType.clear(); // no deps= for multiple outputs
     rule.DepFile = "$DEP_FILE";
   }
 
diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx
index 6c53b85..44f37cb 100644
--- a/Source/cmSearchPath.cxx
+++ b/Source/cmSearchPath.cxx
@@ -179,12 +179,27 @@
       cmValue arch =
         this->FC->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE");
       if (cmNonempty(arch)) {
+        std::string archNoUnknown = arch;
+        auto unknownAtPos = archNoUnknown.find("-unknown-");
+        bool foundUnknown = unknownAtPos != std::string::npos;
+        if (foundUnknown) {
+          // Replace "-unknown-" with "-".
+          archNoUnknown.replace(unknownAtPos, 9, "-");
+        }
         if (this->FC->Makefile->IsDefinitionSet("CMAKE_SYSROOT") &&
             this->FC->Makefile->IsDefinitionSet(
               "CMAKE_PREFIX_LIBRARY_ARCHITECTURE")) {
+          if (foundUnknown) {
+            this->AddPathInternal(cmStrCat('/', archNoUnknown, dir, subdir),
+                                  cmStrCat('/', archNoUnknown, prefix), base);
+          }
           this->AddPathInternal(cmStrCat('/', *arch, dir, subdir),
                                 cmStrCat('/', *arch, prefix), base);
         } else {
+          if (foundUnknown) {
+            this->AddPathInternal(cmStrCat(dir, subdir, '/', archNoUnknown),
+                                  prefix, base);
+          }
           this->AddPathInternal(cmStrCat(dir, subdir, '/', *arch), prefix,
                                 base);
         }
diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx
index cb83873..7a2dd09 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.cxx
+++ b/Source/cmTargetIncludeDirectoriesCommand.cxx
@@ -100,8 +100,7 @@
 {
   return TargetIncludeDirectoriesImpl(status).HandleArguments(
     args, "INCLUDE_DIRECTORIES",
-    static_cast<TargetIncludeDirectoriesImpl::ArgumentFlags>(
-      TargetIncludeDirectoriesImpl::PROCESS_BEFORE |
+    TargetIncludeDirectoriesImpl::PROCESS_BEFORE |
       TargetIncludeDirectoriesImpl::PROCESS_AFTER |
-      TargetIncludeDirectoriesImpl::PROCESS_SYSTEM));
+      TargetIncludeDirectoriesImpl::PROCESS_SYSTEM);
 }
diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx
index 391b954..8d2ff71 100644
--- a/Source/cmTargetPropCommandBase.cxx
+++ b/Source/cmTargetPropCommandBase.cxx
@@ -23,7 +23,7 @@
 
 bool cmTargetPropCommandBase::HandleArguments(
   std::vector<std::string> const& args, const std::string& prop,
-  ArgumentFlags flags)
+  unsigned int flags)
 {
   if (args.size() < 2) {
     this->SetError("called with incorrect number of arguments");
diff --git a/Source/cmTargetPropCommandBase.h b/Source/cmTargetPropCommandBase.h
index 487beb4..ac50b4d 100644
--- a/Source/cmTargetPropCommandBase.h
+++ b/Source/cmTargetPropCommandBase.h
@@ -29,8 +29,7 @@
   };
 
   bool HandleArguments(std::vector<std::string> const& args,
-                       const std::string& prop,
-                       ArgumentFlags flags = NO_FLAGS);
+                       const std::string& prop, unsigned int flags = NO_FLAGS);
 
 protected:
   std::string Property;
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 0fe4919..78615d9 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -760,8 +760,11 @@
 set_property(TEST RunCMake.install APPEND
   PROPERTY LABELS "ISPC")
 
+if(DEFINED CMake_COMPILER_FORCES_NEW_DTAGS)
+  list(APPEND file-GET_RUNTIME_DEPENDENCIES_ARGS
+    -DCMake_COMPILER_FORCES_NEW_DTAGS=${CMake_COMPILER_FORCES_NEW_DTAGS})
+endif()
 add_RunCMake_test(file-GET_RUNTIME_DEPENDENCIES
-  -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
   -DCMake_INSTALL_NAME_TOOL_BUG=${CMake_INSTALL_NAME_TOOL_BUG}
   )
 
diff --git a/Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi.cmake b/Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi.cmake
index 91f3995..88d50db 100644
--- a/Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi.cmake
+++ b/Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi.cmake
@@ -1,6 +1,6 @@
 function (check_for_bmi prefix destination name)
   set(found 0)
-  foreach (ext IN ITEMS gcm ifc)
+  foreach (ext IN ITEMS gcm ifc pcm)
     if (EXISTS "${prefix}/${destination}/${name}.${ext}")
       set(found 1)
       break ()
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake
index 75bfc07..43b406b 100644
--- a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake
@@ -59,7 +59,7 @@
     set(ENV{LDFLAGS} "${new_ldflags}")
   endif()
 
-  if(NOT CMAKE_C_COMPILER_ID MATCHES "^XL")
+  if(NOT CMake_COMPILER_FORCES_NEW_DTAGS)
     run_install_test(linux)
     run_install_test(linux-parent-rpath-propagation)
     run_install_test(file-filter)
diff --git a/Utilities/ClangTidyModule/StringConcatenationUseCmstrcatCheck.cxx b/Utilities/ClangTidyModule/StringConcatenationUseCmstrcatCheck.cxx
index df14c83..e282d23 100644
--- a/Utilities/ClangTidyModule/StringConcatenationUseCmstrcatCheck.cxx
+++ b/Utilities/ClangTidyModule/StringConcatenationUseCmstrcatCheck.cxx
@@ -156,7 +156,8 @@
   ExprNode = *It;
 
   StringRef LastToken = Lexer::getSourceText(
-    CharSourceRange::getTokenRange(ExprNode->getArg(1)->getSourceRange()),
+    CharSourceRange::getTokenRange(
+      ExprNode->getArg(1)->getSourceRange().getEnd()),
     Result.Context->getSourceManager(), Result.Context->getLangOpts());
   FixIts.push_back(FixItHint::CreateInsertion(
     ExprNode->getEndLoc().getLocWithOffset(LastToken.str().size()), ")"));
diff --git a/Utilities/ClangTidyModule/Tests/cmake-string-concatenation-use-cmstrcat-fixit.cxx b/Utilities/ClangTidyModule/Tests/cmake-string-concatenation-use-cmstrcat-fixit.cxx
index 79aecd4..dd1e6c4 100644
--- a/Utilities/ClangTidyModule/Tests/cmake-string-concatenation-use-cmstrcat-fixit.cxx
+++ b/Utilities/ClangTidyModule/Tests/cmake-string-concatenation-use-cmstrcat-fixit.cxx
@@ -1,4 +1,5 @@
 #include <string>
+#include <utility>
 
 template <typename... Args>
 std::string cmStrCat(Args&&... args)
@@ -24,6 +25,9 @@
   concat = cmStrCat(concat, " and this is a string literal");
   concat = cmStrCat(concat, 'o');
   concat = cmStrCat(concat, b, " and this is a string literal ", 'o', b);
+
+  std::pair<std::string, std::string> p;
+  concat = cmStrCat(p.first, p.second);
 }
 
 // No correction needed
diff --git a/Utilities/ClangTidyModule/Tests/cmake-string-concatenation-use-cmstrcat-stdout.txt b/Utilities/ClangTidyModule/Tests/cmake-string-concatenation-use-cmstrcat-stdout.txt
index 3cfdef8..83b8d83 100644
--- a/Utilities/ClangTidyModule/Tests/cmake-string-concatenation-use-cmstrcat-stdout.txt
+++ b/Utilities/ClangTidyModule/Tests/cmake-string-concatenation-use-cmstrcat-stdout.txt
@@ -1,113 +1,124 @@
-cmake-string-concatenation-use-cmstrcat.cxx:16:12: warning: use cmStrCat() instead of string concatenation [cmake-string-concatenation-use-cmstrcat]
+cmake-string-concatenation-use-cmstrcat.cxx:17:12: warning: use cmStrCat() instead of string concatenation [cmake-string-concatenation-use-cmstrcat]
   concat = a + b;
            ^ ~
            cmStrCat( , )
-cmake-string-concatenation-use-cmstrcat.cxx:16:12: note: FIX-IT applied suggested code changes
-cmake-string-concatenation-use-cmstrcat.cxx:16:14: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:17:12: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:17:14: note: FIX-IT applied suggested code changes
   concat = a + b;
              ^
-cmake-string-concatenation-use-cmstrcat.cxx:16:17: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:17:17: note: FIX-IT applied suggested code changes
   concat = a + b;
                 ^
-cmake-string-concatenation-use-cmstrcat.cxx:17:12: warning: use cmStrCat() instead of string concatenation [cmake-string-concatenation-use-cmstrcat]
+cmake-string-concatenation-use-cmstrcat.cxx:18:12: warning: use cmStrCat() instead of string concatenation [cmake-string-concatenation-use-cmstrcat]
   concat = a + " and this is a string literal";
            ^ ~
            cmStrCat( ,                        )
-cmake-string-concatenation-use-cmstrcat.cxx:17:12: note: FIX-IT applied suggested code changes
-cmake-string-concatenation-use-cmstrcat.cxx:17:14: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:18:12: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:18:14: note: FIX-IT applied suggested code changes
   concat = a + " and this is a string literal";
              ^
-cmake-string-concatenation-use-cmstrcat.cxx:17:47: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:18:47: note: FIX-IT applied suggested code changes
   concat = a + " and this is a string literal";
                                               ^
-cmake-string-concatenation-use-cmstrcat.cxx:18:12: warning: use cmStrCat() instead of string concatenation [cmake-string-concatenation-use-cmstrcat]
+cmake-string-concatenation-use-cmstrcat.cxx:19:12: warning: use cmStrCat() instead of string concatenation [cmake-string-concatenation-use-cmstrcat]
   concat = a + 'O';
            ^ ~
            cmStrCat( , )
-cmake-string-concatenation-use-cmstrcat.cxx:18:12: note: FIX-IT applied suggested code changes
-cmake-string-concatenation-use-cmstrcat.cxx:18:14: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:19:12: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:19:14: note: FIX-IT applied suggested code changes
   concat = a + 'O';
              ^
-cmake-string-concatenation-use-cmstrcat.cxx:18:19: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:19:19: note: FIX-IT applied suggested code changes
   concat = a + 'O';
                   ^
-cmake-string-concatenation-use-cmstrcat.cxx:19:12: warning: use cmStrCat() instead of string concatenation [cmake-string-concatenation-use-cmstrcat]
+cmake-string-concatenation-use-cmstrcat.cxx:20:12: warning: use cmStrCat() instead of string concatenation [cmake-string-concatenation-use-cmstrcat]
   concat = "This is a string literal" + b;
            ^                          ~
            cmStrCat(                  ,  )
-cmake-string-concatenation-use-cmstrcat.cxx:19:12: note: FIX-IT applied suggested code changes
-cmake-string-concatenation-use-cmstrcat.cxx:19:39: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:20:12: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:20:39: note: FIX-IT applied suggested code changes
   concat = "This is a string literal" + b;
                                       ^
-cmake-string-concatenation-use-cmstrcat.cxx:19:42: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:20:42: note: FIX-IT applied suggested code changes
   concat = "This is a string literal" + b;
                                          ^
-cmake-string-concatenation-use-cmstrcat.cxx:20:12: warning: use cmStrCat() instead of string concatenation [cmake-string-concatenation-use-cmstrcat]
+cmake-string-concatenation-use-cmstrcat.cxx:21:12: warning: use cmStrCat() instead of string concatenation [cmake-string-concatenation-use-cmstrcat]
   concat = 'O' + a;
            ^   ~
            cmStrCat( , )
-cmake-string-concatenation-use-cmstrcat.cxx:20:12: note: FIX-IT applied suggested code changes
-cmake-string-concatenation-use-cmstrcat.cxx:20:16: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:21:12: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:21:16: note: FIX-IT applied suggested code changes
   concat = 'O' + a;
                ^
-cmake-string-concatenation-use-cmstrcat.cxx:20:19: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:21:19: note: FIX-IT applied suggested code changes
   concat = 'O' + a;
                   ^
-cmake-string-concatenation-use-cmstrcat.cxx:21:12: warning: use cmStrCat() instead of string concatenation [cmake-string-concatenation-use-cmstrcat]
+cmake-string-concatenation-use-cmstrcat.cxx:22:12: warning: use cmStrCat() instead of string concatenation [cmake-string-concatenation-use-cmstrcat]
   concat = a + " and this is a string literal" + 'O' + b;
            ^ ~                                 ~     ~
            cmStrCat( ,                         ,     ,  )
-cmake-string-concatenation-use-cmstrcat.cxx:21:12: note: FIX-IT applied suggested code changes
-cmake-string-concatenation-use-cmstrcat.cxx:21:14: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:22:12: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:22:14: note: FIX-IT applied suggested code changes
   concat = a + " and this is a string literal" + 'O' + b;
              ^
-cmake-string-concatenation-use-cmstrcat.cxx:21:48: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:22:48: note: FIX-IT applied suggested code changes
   concat = a + " and this is a string literal" + 'O' + b;
                                                ^
-cmake-string-concatenation-use-cmstrcat.cxx:21:54: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:22:54: note: FIX-IT applied suggested code changes
   concat = a + " and this is a string literal" + 'O' + b;
                                                      ^
-cmake-string-concatenation-use-cmstrcat.cxx:21:57: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:22:57: note: FIX-IT applied suggested code changes
   concat = a + " and this is a string literal" + 'O' + b;
                                                         ^
-cmake-string-concatenation-use-cmstrcat.cxx:23:10: warning: use cmStrCat() instead of string append [cmake-string-concatenation-use-cmstrcat]
+cmake-string-concatenation-use-cmstrcat.cxx:24:10: warning: use cmStrCat() instead of string append [cmake-string-concatenation-use-cmstrcat]
   concat += b;
          ^~
          = cmStrCat(concat, )
-cmake-string-concatenation-use-cmstrcat.cxx:23:10: note: FIX-IT applied suggested code changes
-cmake-string-concatenation-use-cmstrcat.cxx:23:14: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:24:10: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:24:14: note: FIX-IT applied suggested code changes
   concat += b;
              ^
-cmake-string-concatenation-use-cmstrcat.cxx:24:10: warning: use cmStrCat() instead of string append [cmake-string-concatenation-use-cmstrcat]
+cmake-string-concatenation-use-cmstrcat.cxx:25:10: warning: use cmStrCat() instead of string append [cmake-string-concatenation-use-cmstrcat]
   concat += " and this is a string literal";
          ^~
          = cmStrCat(concat,                )
-cmake-string-concatenation-use-cmstrcat.cxx:24:10: note: FIX-IT applied suggested code changes
-cmake-string-concatenation-use-cmstrcat.cxx:24:44: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:25:10: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:25:44: note: FIX-IT applied suggested code changes
   concat += " and this is a string literal";
                                            ^
-cmake-string-concatenation-use-cmstrcat.cxx:25:10: warning: use cmStrCat() instead of string append [cmake-string-concatenation-use-cmstrcat]
+cmake-string-concatenation-use-cmstrcat.cxx:26:10: warning: use cmStrCat() instead of string append [cmake-string-concatenation-use-cmstrcat]
   concat += 'o';
          ^~
          = cmStrCat(concat, )
-cmake-string-concatenation-use-cmstrcat.cxx:25:10: note: FIX-IT applied suggested code changes
-cmake-string-concatenation-use-cmstrcat.cxx:25:16: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:26:10: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:26:16: note: FIX-IT applied suggested code changes
   concat += 'o';
                ^
-cmake-string-concatenation-use-cmstrcat.cxx:26:10: warning: use cmStrCat() instead of string append [cmake-string-concatenation-use-cmstrcat]
+cmake-string-concatenation-use-cmstrcat.cxx:27:10: warning: use cmStrCat() instead of string append [cmake-string-concatenation-use-cmstrcat]
   concat += b + " and this is a string literal " + 'o' + b;
          ^~   ~                                  ~     ~
          = cmStrCat(concat, ,                    ,     ,  )
-cmake-string-concatenation-use-cmstrcat.cxx:26:10: note: FIX-IT applied suggested code changes
-cmake-string-concatenation-use-cmstrcat.cxx:26:15: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:27:10: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:27:15: note: FIX-IT applied suggested code changes
   concat += b + " and this is a string literal " + 'o' + b;
               ^
-cmake-string-concatenation-use-cmstrcat.cxx:26:50: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:27:50: note: FIX-IT applied suggested code changes
   concat += b + " and this is a string literal " + 'o' + b;
                                                  ^
-cmake-string-concatenation-use-cmstrcat.cxx:26:56: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:27:56: note: FIX-IT applied suggested code changes
   concat += b + " and this is a string literal " + 'o' + b;
                                                        ^
-cmake-string-concatenation-use-cmstrcat.cxx:26:59: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:27:59: note: FIX-IT applied suggested code changes
   concat += b + " and this is a string literal " + 'o' + b;
                                                           ^
+cmake-string-concatenation-use-cmstrcat.cxx:30:12: warning: use cmStrCat() instead of string concatenation [cmake-string-concatenation-use-cmstrcat]
+  concat = p.first + p.second;
+           ^       ~
+           cmStrCat( ,       )
+cmake-string-concatenation-use-cmstrcat.cxx:30:12: note: FIX-IT applied suggested code changes
+cmake-string-concatenation-use-cmstrcat.cxx:30:20: note: FIX-IT applied suggested code changes
+  concat = p.first + p.second;
+                   ^
+cmake-string-concatenation-use-cmstrcat.cxx:30:30: note: FIX-IT applied suggested code changes
+  concat = p.first + p.second;
+                             ^
diff --git a/Utilities/ClangTidyModule/Tests/cmake-string-concatenation-use-cmstrcat.cxx b/Utilities/ClangTidyModule/Tests/cmake-string-concatenation-use-cmstrcat.cxx
index 13a20ac..b088ca3 100644
--- a/Utilities/ClangTidyModule/Tests/cmake-string-concatenation-use-cmstrcat.cxx
+++ b/Utilities/ClangTidyModule/Tests/cmake-string-concatenation-use-cmstrcat.cxx
@@ -1,4 +1,5 @@
 #include <string>
+#include <utility>
 
 template <typename... Args>
 std::string cmStrCat(Args&&... args)
@@ -24,6 +25,9 @@
   concat += " and this is a string literal";
   concat += 'o';
   concat += b + " and this is a string literal " + 'o' + b;
+
+  std::pair<std::string, std::string> p;
+  concat = p.first + p.second;
 }
 
 // No correction needed