r208454 - Don't leak the CXStoredDiagnostics returned by clang_codeCompleteGetDiagnostic()

Nico Weber nicolasweber at gmx.de
Fri May 9 15:33:11 PDT 2014


Author: nico
Date: Fri May  9 17:33:11 2014
New Revision: 208454

URL: http://llvm.org/viewvc/llvm-project?rev=208454&view=rev
Log:
Don't leak the CXStoredDiagnostics returned by clang_codeCompleteGetDiagnostic()

r144269 changed clang_disposeDiagnostic() to be a no-op, but didn't update
code completion diagnostics.  Let CXCodeCompleteResults store all diagnostics
returned by clang_codeCompleteGetDiagnostic() and then free them up in
clang_disposeCodeCompleteResults().

Code completion diagnostics referred to data stored in CXCodeCompleteResults
before already, so it wasn't possible to refer to the results of
clang_codeCompleteGetDiagnostic() after clang_disposeCodeCompleteResults()
before this change already -- hence this should be a safe, backwards-compatible
change.

Leak found by LSan, fixes PR19690.

Modified:
    cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp

Modified: cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp?rev=208454&r1=208453&r2=208454&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp Fri May  9 17:33:11 2014
@@ -255,6 +255,9 @@ struct AllocatedCXCodeCompleteResults :
   /// \brief Diagnostics produced while performing code completion.
   SmallVector<StoredDiagnostic, 8> Diagnostics;
 
+  /// \brief Allocated API-exposed wrappters for Diagnostics.
+  SmallVector<CXStoredDiagnostic *, 8> DiagnosticsWrappers;
+
   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
   
   /// \brief Diag object
@@ -331,6 +334,7 @@ AllocatedCXCodeCompleteResults::Allocate
 }
   
 AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
+  llvm::DeleteContainerPointers(DiagnosticsWrappers);
   delete [] Results;
 
   for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
@@ -722,7 +726,9 @@ void clang_codeCompleteAt_Impl(void *Use
                     *Results->Diag, Results->LangOpts, *Results->SourceMgr,
                     *Results->FileMgr, Results->Diagnostics,
                     Results->TemporaryBuffers);
-  
+
+  Results->DiagnosticsWrappers.resize(Results->Diagnostics.size());
+
   // Keep a reference to the allocator used for cached global completions, so
   // that we can be sure that the memory used by our code completion strings
   // doesn't get freed due to subsequent reparses (while the code completion
@@ -869,7 +875,11 @@ clang_codeCompleteGetDiagnostic(CXCodeCo
   if (!Results || Index >= Results->Diagnostics.size())
     return 0;
 
-  return new CXStoredDiagnostic(Results->Diagnostics[Index], Results->LangOpts);
+  CXStoredDiagnostic *Diag = Results->DiagnosticsWrappers[Index];
+  if (!Diag)
+    Results->DiagnosticsWrappers[Index] = Diag =
+        new CXStoredDiagnostic(Results->Diagnostics[Index], Results->LangOpts);
+  return Diag;
 }
 
 unsigned long long





More information about the cfe-commits mailing list