LINKER_TYPE: Support MOLD only on GCC versions that support it

Fixes: #25748
diff --git a/Modules/Platform/Linux-GNU.cmake b/Modules/Platform/Linux-GNU.cmake
index c3878eb..24bf1bb 100644
--- a/Modules/Platform/Linux-GNU.cmake
+++ b/Modules/Platform/Linux-GNU.cmake
@@ -20,5 +20,8 @@
   set(CMAKE_${lang}_USING_LINKER_LLD "-fuse-ld=lld")
   set(CMAKE_${lang}_USING_LINKER_BFD "-fuse-ld=bfd")
   set(CMAKE_${lang}_USING_LINKER_GOLD "-fuse-ld=gold")
-  set(CMAKE_${lang}_USING_LINKER_MOLD "-fuse-ld=mold")
+  if(NOT CMAKE_${lang}_COMPILER_ID STREQUAL "GNU"
+      OR CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL "12.1")
+    set(CMAKE_${lang}_USING_LINKER_MOLD "-fuse-ld=mold")
+  endif()
 endmacro()
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 46c9082..a40af8b 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -5,6 +5,7 @@
 #include <algorithm>
 #include <array>
 #include <cassert>
+#include <cctype>
 #include <cerrno>
 #include <cstddef>
 #include <cstdio>
@@ -5585,11 +5586,22 @@
     linkerTool = this->Makefile->GetDefinition("CMAKE_LINKER");
 
     if (linkerType != "DEFAULT"_s) {
-      this->LocalGenerator->IssueMessage(
-        MessageType::FATAL_ERROR,
-        cmStrCat("LINKER_TYPE '", linkerType,
-                 "' is unknown. Did you forget to define '", usingLinker,
-                 "' variable?"));
+      auto isCMakeLinkerType = [](const std::string& type) -> bool {
+        return std::all_of(type.cbegin(), type.cend(),
+                           [](char c) { return std::isupper(c); });
+      };
+      if (isCMakeLinkerType(linkerType)) {
+        this->LocalGenerator->IssueMessage(
+          MessageType::FATAL_ERROR,
+          cmStrCat("LINKER_TYPE '", linkerType,
+                   "' is unknown or not supported by this toolchain."));
+      } else {
+        this->LocalGenerator->IssueMessage(
+          MessageType::FATAL_ERROR,
+          cmStrCat("LINKER_TYPE '", linkerType,
+                   "' is unknown. Did you forget to define the '", usingLinker,
+                   "' variable?"));
+      }
     }
   }
 
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 1dd2f4a..d38ed50 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -5,6 +5,7 @@
 #include <algorithm>
 #include <array>
 #include <cassert>
+#include <cctype>
 #include <cstdio>
 #include <cstdlib>
 #include <initializer_list>
@@ -3357,10 +3358,22 @@
       this->AppendFlags(flags, linkerFlags);
     }
   } else if (linkerType != "DEFAULT"_s) {
-    this->IssueMessage(MessageType::FATAL_ERROR,
-                       cmStrCat("LINKER_TYPE '", linkerType,
-                                "' is unknown. Did you forget to define '",
-                                usingLinker, "' variable?"));
+    auto isCMakeLinkerType = [](const std::string& type) -> bool {
+      return std::all_of(type.cbegin(), type.cend(),
+                         [](char c) { return std::isupper(c); });
+    };
+    if (isCMakeLinkerType(linkerType)) {
+      this->IssueMessage(
+        MessageType::FATAL_ERROR,
+        cmStrCat("LINKER_TYPE '", linkerType,
+                 "' is unknown or not supported by this toolchain."));
+    } else {
+      this->IssueMessage(
+        MessageType::FATAL_ERROR,
+        cmStrCat("LINKER_TYPE '", linkerType,
+                 "' is unknown. Did you forget to define the '", usingLinker,
+                 "' variable?"));
+    }
   }
 }
 
diff --git a/Tests/RunCMake/LinkerSelection/InvalidLinkerType-stderr.txt b/Tests/RunCMake/LinkerSelection/InvalidLinkerType-stderr.txt
deleted file mode 100644
index 11aea7a..0000000
--- a/Tests/RunCMake/LinkerSelection/InvalidLinkerType-stderr.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-CMake Error in CMakeLists.txt:
-  LINKER_TYPE 'FOO' is unknown.  Did you forgot to define
-  'CMAKE_C_USING_LINKER_FOO' variable\?
diff --git a/Tests/RunCMake/LinkerSelection/InvalidLinkerType-result.txt b/Tests/RunCMake/LinkerSelection/InvalidLinkerType1-result.txt
similarity index 100%
rename from Tests/RunCMake/LinkerSelection/InvalidLinkerType-result.txt
rename to Tests/RunCMake/LinkerSelection/InvalidLinkerType1-result.txt
diff --git a/Tests/RunCMake/LinkerSelection/InvalidLinkerType1-stderr.txt b/Tests/RunCMake/LinkerSelection/InvalidLinkerType1-stderr.txt
new file mode 100644
index 0000000..5df644e
--- /dev/null
+++ b/Tests/RunCMake/LinkerSelection/InvalidLinkerType1-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error in CMakeLists.txt:
+  LINKER_TYPE 'FOO' is unknown or not supported by this toolchain.
diff --git a/Tests/RunCMake/LinkerSelection/InvalidLinkerType.cmake b/Tests/RunCMake/LinkerSelection/InvalidLinkerType1.cmake
similarity index 100%
rename from Tests/RunCMake/LinkerSelection/InvalidLinkerType.cmake
rename to Tests/RunCMake/LinkerSelection/InvalidLinkerType1.cmake
diff --git a/Tests/RunCMake/LinkerSelection/InvalidLinkerType-result.txt b/Tests/RunCMake/LinkerSelection/InvalidLinkerType2-result.txt
similarity index 100%
copy from Tests/RunCMake/LinkerSelection/InvalidLinkerType-result.txt
copy to Tests/RunCMake/LinkerSelection/InvalidLinkerType2-result.txt
diff --git a/Tests/RunCMake/LinkerSelection/InvalidLinkerType2-stderr.txt b/Tests/RunCMake/LinkerSelection/InvalidLinkerType2-stderr.txt
new file mode 100644
index 0000000..b8c2391
--- /dev/null
+++ b/Tests/RunCMake/LinkerSelection/InvalidLinkerType2-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+  LINKER_TYPE 'foo' is unknown.  Did you forget to define the
+  'CMAKE_C_USING_LINKER_foo' variable\?
diff --git a/Tests/RunCMake/LinkerSelection/InvalidLinkerType2.cmake b/Tests/RunCMake/LinkerSelection/InvalidLinkerType2.cmake
new file mode 100644
index 0000000..9245512
--- /dev/null
+++ b/Tests/RunCMake/LinkerSelection/InvalidLinkerType2.cmake
@@ -0,0 +1,5 @@
+
+enable_language(C)
+
+set(CMAKE_LINKER_TYPE foo)
+add_executable(main main.c)
diff --git a/Tests/RunCMake/LinkerSelection/RunCMakeTest.cmake b/Tests/RunCMake/LinkerSelection/RunCMakeTest.cmake
index cae4ca4..8929a0d 100644
--- a/Tests/RunCMake/LinkerSelection/RunCMakeTest.cmake
+++ b/Tests/RunCMake/LinkerSelection/RunCMakeTest.cmake
@@ -5,7 +5,8 @@
   return()
 endif()
 
-run_cmake(InvalidLinkerType)
+run_cmake(InvalidLinkerType1)
+run_cmake(InvalidLinkerType2)
 
 # look-up for LLVM linker
 if (WIN32)