From 1eca5993e21eeefa8a0c8d4e41b559c1d32c495a Mon Sep 17 00:00:00 2001
From: Marc Chevrier <marc.chevrier@gmail.com>
Date: Thu, 28 May 2020 14:52:57 +0200
Subject: ALIAS target: cannot overwrite an existing target

Fixes: #19616
---
 Help/manual/cmake-policies.7.rst                   |  1 +
 Help/policy/CMP0107.rst                            | 19 ++++++++++++++
 Help/release/dev/alias-overwrite.rst               |  5 ++++
 Source/cmAddLibraryCommand.cxx                     | 11 ++++++++
 Source/cmPolicies.h                                |  4 ++-
 Tests/RunCMake/alias_targets/RunCMakeTest.cmake    |  2 ++
 .../duplicate-target-CMP0107-NEW-result.txt        |  1 +
 .../duplicate-target-CMP0107-NEW-stderr.txt        | 30 ++++++++++++++++++++++
 .../duplicate-target-CMP0107-NEW.cmake             |  4 +++
 .../duplicate-target-CMP0107-OLD.cmake             |  4 +++
 .../RunCMake/alias_targets/duplicate-target.cmake  | 20 +++++++++++++++
 11 files changed, 100 insertions(+), 1 deletion(-)
 create mode 100644 Help/policy/CMP0107.rst
 create mode 100644 Help/release/dev/alias-overwrite.rst
 create mode 100644 Tests/RunCMake/alias_targets/duplicate-target-CMP0107-NEW-result.txt
 create mode 100644 Tests/RunCMake/alias_targets/duplicate-target-CMP0107-NEW-stderr.txt
 create mode 100644 Tests/RunCMake/alias_targets/duplicate-target-CMP0107-NEW.cmake
 create mode 100644 Tests/RunCMake/alias_targets/duplicate-target-CMP0107-OLD.cmake
 create mode 100644 Tests/RunCMake/alias_targets/duplicate-target.cmake

diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 3f3b70d..8d41ed8 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -57,6 +57,7 @@ Policies Introduced by CMake 3.18
 .. toctree::
    :maxdepth: 1
 
+   CMP0107: An ALIAS target cannot overwrite another target. </policy/CMP0107>
    CMP0106: The Documentation module is removed. </policy/CMP0106>
    CMP0105: Device link step uses the link options. </policy/CMP0105>
    CMP0104: CMAKE_CUDA_ARCHITECTURES now detected for NVCC, empty CUDA_ARCHITECTURES not allowed. </policy/CMP0104>
diff --git a/Help/policy/CMP0107.rst b/Help/policy/CMP0107.rst
new file mode 100644
index 0000000..111bef7
--- /dev/null
+++ b/Help/policy/CMP0107.rst
@@ -0,0 +1,19 @@
+CMP0107
+-------
+
+It is not allowed to create an ``ALIAS`` target with the same name as an
+another target.
+
+In CMake 3.17 and below, an ``ALIAS`` target can overwrite silently an existing
+target with the same name.
+
+The ``OLD`` behavior for this policy is to allow target overwrite.
+
+The ``NEW`` behavior of this policy is to prevent target overwriting.
+
+This policy was introduced in CMake version 3.17.  Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+Unlike many policies, CMake version |release| does *not* warn
+when this policy is not set and simply uses ``OLD`` behavior.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/release/dev/alias-overwrite.rst b/Help/release/dev/alias-overwrite.rst
new file mode 100644
index 0000000..907e630
--- /dev/null
+++ b/Help/release/dev/alias-overwrite.rst
@@ -0,0 +1,5 @@
+alias-overwrite
+---------------
+
+* Creation of an ``ALIAS`` target overwriting an existing target now raise an
+  error. See policy :policy:`CMP0107`.
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index f443fc6..d79c04f 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -9,6 +9,7 @@
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
+#include "cmPolicies.h"
 #include "cmState.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
@@ -181,6 +182,16 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
       return false;
     }
 
+    if (mf.GetPolicyStatus(cmPolicies::CMP0107) == cmPolicies::NEW) {
+      // Make sure the target does not already exist.
+      if (mf.FindTargetToUse(libName)) {
+        status.SetError(cmStrCat(
+          "cannot create ALIAS target \"", libName,
+          "\" because another target with the same name already exists."));
+        return false;
+      }
+    }
+
     std::string const& aliasedName = *s;
     if (mf.IsAlias(aliasedName)) {
       status.SetError(cmStrCat("cannot create ALIAS target \"", libName,
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 4abfa1f..4dff1d8 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -316,7 +316,9 @@ class cmMakefile;
   SELECT(POLICY, CMP0105, "Device link step uses the link options.", 3, 18,   \
          0, cmPolicies::WARN)                                                 \
   SELECT(POLICY, CMP0106, "The Documentation module is removed.", 3, 18, 0,   \
-         cmPolicies::WARN)
+         cmPolicies::WARN)                                                    \
+  SELECT(POLICY, CMP0107, "An ALIAS target cannot overwrite another target.", \
+         3, 18, 0, cmPolicies::WARN)
 
 #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
 #define CM_FOR_EACH_POLICY_ID(POLICY)                                         \
diff --git a/Tests/RunCMake/alias_targets/RunCMakeTest.cmake b/Tests/RunCMake/alias_targets/RunCMakeTest.cmake
index dded248..676de08 100644
--- a/Tests/RunCMake/alias_targets/RunCMakeTest.cmake
+++ b/Tests/RunCMake/alias_targets/RunCMakeTest.cmake
@@ -2,6 +2,8 @@ include(RunCMake)
 
 run_cmake(no-targets)
 run_cmake(multiple-targets)
+run_cmake(duplicate-target-CMP0107-OLD)
+run_cmake(duplicate-target-CMP0107-NEW)
 run_cmake(exclude-from-all)
 run_cmake(imported)
 run_cmake(invalid-name)
diff --git a/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-NEW-result.txt b/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-NEW-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-NEW-stderr.txt b/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-NEW-stderr.txt
new file mode 100644
index 0000000..03ba5a6
--- /dev/null
+++ b/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-NEW-stderr.txt
@@ -0,0 +1,30 @@
+CMake Error at duplicate-target.cmake:[0-9]+ \(add_library\):
+  add_library cannot create ALIAS target "alias1" because another target with
+  the same name already exists.
+Call Stack \(most recent call first\):
+  duplicate-target-CMP0107-NEW.cmake:[0-9]+ \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)
+
+
+CMake Error at duplicate-target.cmake:[0-9]+ \(add_library\):
+  add_library cannot create ALIAS target "alias1" because another target with
+  the same name already exists.
+Call Stack \(most recent call first\):
+  duplicate-target-CMP0107-NEW.cmake:[0-9]+ \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)
+
+
+CMake Error at duplicate-target.cmake:[0-9]+ \(add_library\):
+  add_library cannot create ALIAS target "alias2" because another target with
+  the same name already exists.
+Call Stack \(most recent call first\):
+  duplicate-target-CMP0107-NEW.cmake:[0-9]+ \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)
+
+
+CMake Error at duplicate-target.cmake:[0-9]+ \(add_library\):
+  add_library cannot create ALIAS target "alias2" because another target with
+  the same name already exists.
+Call Stack \(most recent call first\):
+  duplicate-target-CMP0107-NEW.cmake:[0-9]+ \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-NEW.cmake b/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-NEW.cmake
new file mode 100644
index 0000000..609857f
--- /dev/null
+++ b/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-NEW.cmake
@@ -0,0 +1,4 @@
+
+cmake_policy (SET CMP0107 NEW)
+
+include (duplicate-target.cmake)
diff --git a/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-OLD.cmake b/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-OLD.cmake
new file mode 100644
index 0000000..d5bc998
--- /dev/null
+++ b/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-OLD.cmake
@@ -0,0 +1,4 @@
+
+cmake_policy (SET CMP0107 OLD)
+
+include (duplicate-target.cmake)
diff --git a/Tests/RunCMake/alias_targets/duplicate-target.cmake b/Tests/RunCMake/alias_targets/duplicate-target.cmake
new file mode 100644
index 0000000..f81921b
--- /dev/null
+++ b/Tests/RunCMake/alias_targets/duplicate-target.cmake
@@ -0,0 +1,20 @@
+
+add_library (foo1 INTERFACE)
+add_library (foo2 INTERFACE)
+
+add_library (imp1 SHARED IMPORTED GLOBAL)
+add_library (imp2 SHARED IMPORTED GLOBAL)
+
+
+add_library (alias1 ALIAS foo1)
+# same alias to different library
+add_library (alias1 ALIAS foo2)
+# same alias to different imported library
+add_library (alias1 ALIAS imp1)
+
+
+add_library (alias2 ALIAS imp1)
+# same alias to different imported library
+add_library (alias2 ALIAS imp2)
+# same alias to different library
+add_library (alias2 ALIAS foo1)
-- 
cgit v0.12