From 45ed175f0898fb407dbc327b660449e1d773c197 Mon Sep 17 00:00:00 2001
From: Marc Chevrier <marc.chevrier@gmail.com>
Date: Thu, 17 Aug 2023 11:47:20 +0200
Subject: list(INSERT): restore old behavior

Fixes: #25191
---
 Source/cmGeneratorExpressionNode.cxx      |  4 ++-
 Source/cmList.h                           | 15 ++++++++--
 Source/cmListCommand.cxx                  |  3 +-
 Tests/CMakeTests/ListTest.cmake.in        | 21 ++++++++++++++
 Tests/RunCMake/GenEx-LIST/INSERT.cmake.in | 47 +++++++++++++++++++++++++++++++
 5 files changed, 86 insertions(+), 4 deletions(-)

diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 7fe814a..4c80d4b 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -1360,7 +1360,9 @@ static const struct ListNode : public cmGeneratorExpressionNode
               try {
                 auto list = GetList(args.front());
                 args.advance(2);
-                list.insert_items(index, args.begin(), args.end());
+                list.insert_items(index, args.begin(), args.end(),
+                                  cmList::ExpandElements::No,
+                                  cmList::EmptyElements::Yes);
                 return list.to_string();
               } catch (std::out_of_range& e) {
                 reportError(ctx, cnt->GetOriginalExpression(), e.what());
diff --git a/Source/cmList.h b/Source/cmList.h
index 798b984..df450fd 100644
--- a/Source/cmList.h
+++ b/Source/cmList.h
@@ -740,9 +740,20 @@ public:
   // Throw std::out_of_range if index is invalid
   template <typename InputIterator>
   cmList& insert_items(index_type index, InputIterator first,
-                       InputIterator last)
+                       InputIterator last,
+                       ExpandElements expandElements = ExpandElements::Yes,
+                       EmptyElements emptyElements = EmptyElements::No)
   {
-    this->insert(this->begin() + this->ComputeInsertIndex(index), first, last);
+    this->insert(this->begin() + this->ComputeInsertIndex(index), first, last,
+                 expandElements, emptyElements);
+    return *this;
+  }
+  template <typename InputIterator>
+  cmList& insert_items(index_type index, InputIterator first,
+                       InputIterator last, EmptyElements emptyElements)
+  {
+    this->insert(this->begin() + this->ComputeInsertIndex(index), first, last,
+                 ExpandElements::Yes, emptyElements);
     return *this;
   }
   cmList& insert_items(index_type index,
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index acffa2e..ebf5841 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -375,7 +375,8 @@ bool HandleInsertCommand(std::vector<std::string> const& args,
   }
 
   try {
-    list->insert_items(index, args.begin() + 3, args.end());
+    list->insert_items(index, args.begin() + 3, args.end(),
+                       cmList::ExpandElements::No, cmList::EmptyElements::Yes);
     status.GetMakefile().AddDefinition(listName, list->to_string());
     return true;
   } catch (std::out_of_range& e) {
diff --git a/Tests/CMakeTests/ListTest.cmake.in b/Tests/CMakeTests/ListTest.cmake.in
index 76737e5..0120c84 100644
--- a/Tests/CMakeTests/ListTest.cmake.in
+++ b/Tests/CMakeTests/ListTest.cmake.in
@@ -161,3 +161,24 @@ foreach (_pol ${thelist})
         message(SEND_ERROR "returned element '${thevalue}', but expected '${_pol}'")
     endif()
 endforeach (_pol)
+
+block(SCOPE_FOR POLICIES)
+  cmake_policy(SET CMP0007 NEW)
+  set(result andy bill brad ken bob)
+  list(INSERT result 1 "")
+  TEST("INSERT result 1 \"\"" "andy;;bill;brad;ken;bob")
+  list(INSERT result 4 ";")
+  TEST("INSERT result 1 ;" "andy;;bill;brad;;;ken;bob")
+  list(INSERT result 0 "x")
+  TEST("INSERT result 1 x" "x;andy;;bill;brad;;;ken;bob")
+endblock()
+block(SCOPE_FOR POLICIES)
+  cmake_policy(SET CMP0007 OLD)
+  set(result andy bill brad ken bob)
+  list(INSERT result 1 "")
+  TEST("INSERT result 1 \"\"" "andy;;bill;brad;ken;bob")
+  list(INSERT result 4 ";")
+  TEST("INSERT result 1 ;" "andy;bill;brad;ken;;;bob")
+  list(INSERT result 0 "x")
+  TEST("INSERT result 1 x" "x;andy;bill;brad;ken;bob")
+endblock()
diff --git a/Tests/RunCMake/GenEx-LIST/INSERT.cmake.in b/Tests/RunCMake/GenEx-LIST/INSERT.cmake.in
index d3bb9b9..48add61 100644
--- a/Tests/RunCMake/GenEx-LIST/INSERT.cmake.in
+++ b/Tests/RunCMake/GenEx-LIST/INSERT.cmake.in
@@ -46,5 +46,52 @@ if (NOT output STREQUAL listvar)
   list (APPEND errors "returns bad value: ${output}")
 endif()
 
+block(SCOPE_FOR POLICIES)
+  cmake_policy(SET CMP0007 NEW)
+
+  set(listvar "0;1;2;3;4")
+  list(INSERT listvar 1 "")
+  set (output "$<LIST:INSERT,0;1;2;3;4,1,>")
+  if (NOT output STREQUAL listvar)
+    list (APPEND errors "returns bad value: ${output}")
+  endif()
+
+  list(INSERT listvar 4 ";")
+  set (output "$<LIST:INSERT,0;;1;2;3;4,4,;>")
+  if (NOT output STREQUAL listvar)
+    list (APPEND errors "returns bad value: ${output}")
+  endif()
+
+  list(INSERT listvar 0 "x")
+  set (output "$<LIST:INSERT,0;;1;2;;;3;4,0,x>")
+  if (NOT output STREQUAL listvar)
+    list (APPEND errors "returns bad value: ${output}")
+  endif()
+endblock()
+block(SCOPE_FOR POLICIES)
+  set(CMAKE_WARN_DEPRECATED OFF CACHE BOOL "")
+  cmake_policy(SET CMP0007 OLD)
+
+  set(listvar "0;1;2;3;4")
+  list(INSERT listvar 1 "")
+  set (output "$<LIST:INSERT,0;1;2;3;4,1,>")
+  if (NOT output STREQUAL listvar)
+    list (APPEND errors "returns bad value: ${output}")
+  endif()
+
+  list(INSERT listvar 4 ";")
+  set (output "$<LIST:INSERT,0;1;2;3;4,4,;>")
+  if (NOT output STREQUAL listvar)
+    list (APPEND errors "returns bad value: ${output}")
+  endif()
+
+  list(INSERT listvar 0 "x")
+  set (output "$<LIST:INSERT,0;1;2;3;4,0,x>")
+  if (NOT output STREQUAL listvar)
+    list (APPEND errors "returns bad value: ${output}")
+  endif()
+
+  unset(CMAKE_WARN_DEPRECATED CACHE)
+endblock()
 
 check_errors("LIST:INSERT..." ${errors})
-- 
cgit v0.12