diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h
index a190e1f..b42133b 100644
--- a/include/clang/StaticAnalyzer/Core/Checker.h
+++ b/include/clang/StaticAnalyzer/Core/Checker.h
@@ -323,10 +323,12 @@ class PointerEscape {
   _checkPointerEscape(void *checker,
                      ProgramStateRef State,
                      const InvalidatedSymbols &Escaped,
-                     const CallEvent *Call) {
+                     const CallEvent *Call,
+                     const enum PointerEscapeKind Kind) {
     return ((const CHECKER *)checker)->checkPointerEscape(State, 
                                                           Escaped, 
-                                                          Call);
+                                                          Call,
+                                                          Kind);
   }
 
 public:
diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h
index 2fd71dd..b79340c 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerManager.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -112,6 +112,27 @@ public:
   RET operator()() const { return Fn(Checker); } 
 };
 
+/// \brief Describes the different reasons a pointer escapes
+/// during analysis.
+enum PointerEscapeKind {
+  /// A pointer escapes due to binding its value to a location,
+  /// preventing further reasoning on the pointer.
+  PSK_EscapeOnBind = 1,
+
+  /// The pointer has been passed to a function call directly.
+  PSK_DirectEscapeOnCall,
+
+  /// The pointer has been passed to a function indirectly.
+  /// For example, the pointer is accessable through an
+  /// argument to a function.
+  PSK_IndirectEscapeOnCall,
+
+  ///The reason for pointer escape is unknown. For example, a checker
+  ///invalidates a region and intends the invalidation to cause a
+  ///pointer escape event.
+  PSK_EscapeOther
+};
+
 class CheckerManager {
   const LangOptions LangOpts;
 
@@ -330,7 +351,8 @@ public:
   ProgramStateRef 
   runCheckersForPointerEscape(ProgramStateRef State,
                               const InvalidatedSymbols &Escaped,
-                              const CallEvent *Call);
+                              const CallEvent *Call,
+                              const enum PointerEscapeKind Kind);
 
   /// \brief Run checkers for handling assumptions on symbolic values.
   ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
@@ -420,7 +442,8 @@ public:
 
   typedef CheckerFn<ProgramStateRef (ProgramStateRef,
                                      const InvalidatedSymbols &Escaped,
-                                     const CallEvent *Call)>
+                                     const CallEvent *Call,
+                                     const enum PointerEscapeKind Kind)>
       CheckPointerEscapeFunc;
   
   typedef CheckerFn<ProgramStateRef (ProgramStateRef,
diff --git a/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp b/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
index 35baef6..9e43e4f 100644
--- a/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
+++ b/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
@@ -265,10 +265,12 @@ public:
   /// \param Escaped The list of escaped symbols.
   /// \param Call The corresponding CallEvent, if the symbols escape as 
   /// parameters to the given call.
+  /// \param Kind The kind of escape the pointers have undergone.
   /// \returns Checkers can modify the state by returning a new state.
   ProgramStateRef checkPointerEscape(ProgramStateRef State,
-                                     const InvalidatedSymbols &Escaped,
-                                     const CallEvent *Call) const {
+                            const InvalidatedSymbols &Escaped,
+                            const CallEvent *Call,
+                            const enum PointerEscapeKind Kind) const {
     return State;
   }
 
diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 33553a1..c6a07a0 100644
--- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -157,8 +157,9 @@ public:
                      CheckerContext &C) const;
 
   ProgramStateRef checkPointerEscape(ProgramStateRef State,
-                                    const InvalidatedSymbols &Escaped,
-                                    const CallEvent *Call) const;
+                            const InvalidatedSymbols &Escaped,
+                            const CallEvent *Call,
+                            const enum PointerEscapeKind Kind) const;
 
   void printState(raw_ostream &Out, ProgramStateRef State,
                   const char *NL, const char *Sep) const;
@@ -1449,12 +1450,16 @@ bool MallocChecker::doesNotFreeMemory(const CallEvent *Call,
 }
 
 ProgramStateRef MallocChecker::checkPointerEscape(ProgramStateRef State,
-                                             const InvalidatedSymbols &Escaped,
-                                             const CallEvent *Call) const {
+                          const InvalidatedSymbols &Escaped,
+                          const CallEvent *Call,
+                          const enum PointerEscapeKind Kind) const {
   // If we know that the call does not free memory, keep tracking the top
   // level arguments.       
-  if (Call && doesNotFreeMemory(Call, State))
+  if ((Kind == PSK_DirectEscapeOnCall ||
+      Kind == PSK_IndirectEscapeOnCall) &&
+      doesNotFreeMemory(Call, State)) {
     return State;
+  }
 
   for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
                                           E = Escaped.end();
diff --git a/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp b/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp
index e2a19fc..8c467bc 100644
--- a/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp
@@ -81,8 +81,9 @@ public:
 
   /// Stop tracking addresses which escape.
   ProgramStateRef checkPointerEscape(ProgramStateRef State,
-                                    const InvalidatedSymbols &Escaped,
-                                    const CallEvent *Call) const;
+                            const InvalidatedSymbols &Escaped,
+                            const CallEvent *Call,
+                            const enum PointerEscapeKind Kind) const;
 };
 
 } // end anonymous namespace
@@ -254,11 +255,15 @@ bool SimpleStreamChecker::guaranteedNotToCloseFile(const CallEvent &Call) const{
 // we cannot reason about it anymore.
 ProgramStateRef
 SimpleStreamChecker::checkPointerEscape(ProgramStateRef State,
-                                        const InvalidatedSymbols &Escaped,
-                                        const CallEvent *Call) const {
+                          const InvalidatedSymbols &Escaped,
+                          const CallEvent *Call,
+                          const enum PointerEscapeKind Kind) const {
   // If we know that the call cannot close a file, there is nothing to do.
-  if (Call && guaranteedNotToCloseFile(*Call))
+  if ((Kind == PSK_DirectEscapeOnCall ||
+      Kind == PSK_IndirectEscapeOnCall) &&
+      guaranteedNotToCloseFile(*Call)) {
     return State;
+  }
 
   for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
                                           E = Escaped.end();
diff --git a/lib/StaticAnalyzer/Core/CheckerManager.cpp b/lib/StaticAnalyzer/Core/CheckerManager.cpp
index dc0cab7..eccb6e2 100644
--- a/lib/StaticAnalyzer/Core/CheckerManager.cpp
+++ b/lib/StaticAnalyzer/Core/CheckerManager.cpp
@@ -487,14 +487,18 @@ CheckerManager::runCheckersForRegionChanges(ProgramStateRef state,
 /// \brief Run checkers to process symbol escape event.
 ProgramStateRef
 CheckerManager::runCheckersForPointerEscape(ProgramStateRef State,
-                                           const InvalidatedSymbols &Escaped,
-                                           const CallEvent *Call) {
+                                  const InvalidatedSymbols &Escaped,
+                                  const CallEvent *Call,
+                                  const enum PointerEscapeKind Kind) {
+  assert((Kind == PSK_DirectEscapeOnCall ||
+          Kind == PSK_IndirectEscapeOnCall) ?
+          Call != NULL : true);
   for (unsigned i = 0, e = PointerEscapeCheckers.size(); i != e; ++i) {
     // If any checker declares the state infeasible (or if it starts that way),
     // bail out.
     if (!State)
       return NULL;
-    State = PointerEscapeCheckers[i](State, Escaped, Call);
+    State = PointerEscapeCheckers[i](State, Escaped, Call, Kind);
   }
   return State;
 }
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index f2b8c30..0b3a300 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1640,8 +1640,9 @@ ProgramStateRef ExprEngine::processPointerEscapedOnBind(ProgramStateRef State,
       State->scanReachableSymbols<CollectReachableSymbolsCallback>(Val);
   const InvalidatedSymbols &EscapedSymbols = Scanner.getSymbols();
   State = getCheckerManager().runCheckersForPointerEscape(State,
-                                                          EscapedSymbols,
-                                                          /*CallEvent*/ 0);
+                                                      EscapedSymbols,
+                                                      /*CallEvent*/ 0,
+                                                      PSK_EscapeOnBind);
 
   return State;
 }
@@ -1658,7 +1659,9 @@ ExprEngine::processPointerEscapedOnInvalidateRegions(ProgramStateRef State,
 
   if (!Call)
     return getCheckerManager().runCheckersForPointerEscape(State,
-                                                           *Invalidated, 0);
+                                                       *Invalidated,
+                                                       0,
+                                                       PSK_EscapeOther);
     
   // If the symbols were invalidated by a call, we want to find out which ones 
   // were invalidated directly due to being arguments to the call.
@@ -1680,12 +1683,12 @@ ExprEngine::processPointerEscapedOnInvalidateRegions(ProgramStateRef State,
 
   if (!SymbolsDirectlyInvalidated.empty())
     State = getCheckerManager().runCheckersForPointerEscape(State,
-        SymbolsDirectlyInvalidated, Call);
+        SymbolsDirectlyInvalidated, Call, PSK_DirectEscapeOnCall);
 
   // Notify about the symbols that get indirectly invalidated by the call.
   if (!SymbolsIndirectlyInvalidated.empty())
     State = getCheckerManager().runCheckersForPointerEscape(State,
-        SymbolsIndirectlyInvalidated, /*CallEvent*/ 0);
+        SymbolsIndirectlyInvalidated, Call, PSK_IndirectEscapeOnCall);
 
   return State;
 }
