set: warn if CACHE type is not recognized
diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx
index 1a2d1c6..b09e3ca 100644
--- a/Source/cmSetCommand.cxx
+++ b/Source/cmSetCommand.cxx
@@ -4,6 +4,7 @@
 
 #include "cmAlgorithms.h"
 #include "cmMakefile.h"
+#include "cmMessageType.h"
 #include "cmState.h"
 #include "cmStateTypes.h"
 #include "cmSystemTools.h"
@@ -112,7 +113,15 @@
 
   if (cache) {
     std::string::size_type cacheStart = args.size() - 3 - (force ? 1 : 0);
-    type = cmState::StringToCacheEntryType(args[cacheStart + 1].c_str());
+    if (!cmState::StringToCacheEntryType(args[cacheStart + 1].c_str(), type)) {
+      std::string m = "implicitly converting '" + args[cacheStart + 1] +
+        "' to 'STRING' type.";
+      this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, m);
+      // Setting this may not be required, since it's
+      // initialized as a string. Keeping this here to
+      // ensure that the type is actually converting to a string.
+      type = cmStateEnums::STRING;
+    }
     docstring = args[cacheStart + 2].c_str();
   }
 
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index fdd7b3d..a08e9b8 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -75,14 +75,23 @@
 
 cmStateEnums::CacheEntryType cmState::StringToCacheEntryType(const char* s)
 {
+  cmStateEnums::CacheEntryType type = cmStateEnums::STRING;
+  StringToCacheEntryType(s, type);
+  return type;
+}
+
+bool cmState::StringToCacheEntryType(const char* s,
+                                     cmStateEnums::CacheEntryType& type)
+{
   int i = 0;
   while (cmCacheEntryTypes[i]) {
     if (strcmp(s, cmCacheEntryTypes[i]) == 0) {
-      return static_cast<cmStateEnums::CacheEntryType>(i);
+      type = static_cast<cmStateEnums::CacheEntryType>(i);
+      return true;
     }
     ++i;
   }
-  return cmStateEnums::STRING;
+  return false;
 }
 
 bool cmState::IsCacheEntryType(std::string const& key)
diff --git a/Source/cmState.h b/Source/cmState.h
index e447485..f755f83 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -65,6 +65,8 @@
   cmStateSnapshot Pop(cmStateSnapshot const& originSnapshot);
 
   static cmStateEnums::CacheEntryType StringToCacheEntryType(const char*);
+  static bool StringToCacheEntryType(const char*,
+                                     cmStateEnums::CacheEntryType& type);
   static const char* CacheEntryTypeToString(cmStateEnums::CacheEntryType);
   static bool IsCacheEntryType(std::string const& key);
 
diff --git a/Tests/RunCMake/set/RunCMakeTest.cmake b/Tests/RunCMake/set/RunCMakeTest.cmake
index b8e8cf1..ea63d0b 100644
--- a/Tests/RunCMake/set/RunCMakeTest.cmake
+++ b/Tests/RunCMake/set/RunCMakeTest.cmake
@@ -3,3 +3,4 @@
 run_cmake(ParentScope)
 run_cmake(ParentPulling)
 run_cmake(ParentPullingRecursive)
+run_cmake(UnknownCacheType)
diff --git a/Tests/RunCMake/set/UnknownCacheType-stderr.txt b/Tests/RunCMake/set/UnknownCacheType-stderr.txt
new file mode 100644
index 0000000..6e1c811
--- /dev/null
+++ b/Tests/RunCMake/set/UnknownCacheType-stderr.txt
@@ -0,0 +1,5 @@
+CMake Warning \(dev\) at UnknownCacheType.cmake:1 \(set\):
+  implicitly converting 'unknown_type_sample' to 'STRING' type.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/set/UnknownCacheType.cmake b/Tests/RunCMake/set/UnknownCacheType.cmake
new file mode 100644
index 0000000..f2b5d05
--- /dev/null
+++ b/Tests/RunCMake/set/UnknownCacheType.cmake
@@ -0,0 +1 @@
+set (sample_key sample_value CACHE unknown_type_sample "sample doc")