| 
					
				 | 
			
			
				@@ -17,6 +17,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <utility> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <cm/memory> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <cm/optional> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <cm/string_view> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <cmext/string_view> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -25,7 +26,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "cmListFileCache.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "cmMakefile.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "cmMessageType.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#include "cmProperty.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "cmPolicies.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "cmRange.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "cmStringAlgorithms.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "cmSystemTools.h" 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -113,9 +114,11 @@ bool cmForEachFunctionBlocker::ReplayItems( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // At end of for each execute recorded commands 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // store the old value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  std::string oldDef; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (cmProp d = mf.GetDefinition(this->Args.front())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    oldDef = *d; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cm::optional<std::string> oldDef; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (mf.GetPolicyStatus(cmPolicies::CMP0124) != cmPolicies::NEW) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    oldDef = mf.GetSafeDefinition(this->Args.front()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } else if (mf.IsNormalDefinitionSet(this->Args.front())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    oldDef = *mf.GetDefinition(this->Args.front()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   auto restore = false; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -131,9 +134,14 @@ bool cmForEachFunctionBlocker::ReplayItems( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (restore) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // restore the variable to its prior value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    mf.AddDefinition(this->Args.front(), oldDef); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (oldDef) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // restore the variable to its prior value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      mf.AddDefinition(this->Args.front(), *oldDef); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      mf.RemoveDefinition(this->Args.front()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -185,10 +193,15 @@ bool cmForEachFunctionBlocker::ReplayZipLists( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   assert("Sanity check" && iterationVars.size() == values.size()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // Store old values for iteration variables 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  std::map<std::string, std::string> oldDefs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  std::map<std::string, cm::optional<std::string>> oldDefs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   for (auto i = 0u; i < values.size(); ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (cmProp d = mf.GetDefinition(iterationVars[i])) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      oldDefs.emplace(iterationVars[i], *d); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const auto& varName = iterationVars[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (mf.GetPolicyStatus(cmPolicies::CMP0124) != cmPolicies::NEW) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      oldDefs.emplace(varName, mf.GetSafeDefinition(varName)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else if (mf.IsNormalDefinitionSet(varName)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      oldDefs.emplace(varName, *mf.GetDefinition(varName)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      oldDefs.emplace(varName, cm::nullopt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -226,7 +239,11 @@ bool cmForEachFunctionBlocker::ReplayZipLists( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // Restore the variables to its prior value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (restore) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     for (auto const& p : oldDefs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      mf.AddDefinition(p.first, p.second); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (p.second) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        mf.AddDefinition(p.first, *p.second); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        mf.RemoveDefinition(p.first); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return true; 
			 |