From f841082980f685c127eac3fb3d98cf8961fed55f Mon Sep 17 00:00:00 2001
From: Yves Frederix <yves.frederix@gmail.com>
Date: Wed, 23 Mar 2016 10:37:51 +0100
Subject: [PATCH] Relookup variable value in case it has an associated
 VariableWatch after the watch is processed.

Fixes a problem with 'dep' sometimes becoming invalid due to memory reallocation inside an
std::vector. See https://cmake.org/pipermail/cmake-developers/2016-March/028075.html.
---
 Source/cmMakefile.cxx      | 18 +++++++++++-------
 Source/cmVariableWatch.cxx |  4 +++-
 Source/cmVariableWatch.h   |  2 +-
 3 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 1df5cec..d4ce682 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -2503,15 +2503,19 @@ const char* cmMakefile::GetDefinition(const std::string& name) const
   cmVariableWatch* vv = this->GetVariableWatch();
   if ( vv && !this->SuppressWatches )
     {
-    if ( def )
-      {
-      vv->VariableAccessed(name, cmVariableWatch::VARIABLE_READ_ACCESS,
+    bool watch_function_executed = vv->VariableAccessed(name, 
+        def ? cmVariableWatch::VARIABLE_READ_ACCESS : cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS,
         def, this);
-      }
-    else
+
+    if ( watch_function_executed )
       {
-      vv->VariableAccessed(name,
-          cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS, def, this);
+      // Re-lookup the variable value because 'def' might have become invalid due to the call to
+      // VariableAccessed. See https://cmake.org/pipermail/cmake-developers/2016-March/028075.html.
+      def = this->StateSnapshot.GetDefinition(name);
+      if(!def)
+        {
+        def = this->GetState()->GetInitializedCacheValue(name);
+        }
       }
     }
 #endif
diff --git a/Source/cmVariableWatch.cxx b/Source/cmVariableWatch.cxx
index 57dde31..a200718 100644
--- a/Source/cmVariableWatch.cxx
+++ b/Source/cmVariableWatch.cxx
@@ -96,7 +96,7 @@ void cmVariableWatch::RemoveWatch(const std::string& variable,
     }
 }
 
-void  cmVariableWatch::VariableAccessed(const std::string& variable,
+bool  cmVariableWatch::VariableAccessed(const std::string& variable,
                                         int access_type,
                                         const char* newValue,
                                         const cmMakefile* mf) const
@@ -112,5 +112,7 @@ void  cmVariableWatch::VariableAccessed(const std::string& variable,
       (*it)->Method(variable, access_type, (*it)->ClientData,
         newValue, mf);
       }
+    return true;
     }
+  return false;
 }
diff --git a/Source/cmVariableWatch.h b/Source/cmVariableWatch.h
index 0ca4a55..2f082af 100644
--- a/Source/cmVariableWatch.h
+++ b/Source/cmVariableWatch.h
@@ -42,7 +42,7 @@ public:
   /**
    * This method is called when variable is accessed
    */
-  void VariableAccessed(const std::string& variable, int access_type,
+  bool VariableAccessed(const std::string& variable, int access_type,
     const char* newValue, const cmMakefile* mf) const;
 
   /**
-- 
1.9.5.msysgit.0

