diff options
author | Nico Weber <nicolasweber@gmx.de> | 2014-05-09 22:33:11 +0000 |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2014-05-09 22:33:11 +0000 |
commit | 7dd96c23fd72e2be779857760c66788db0b51df8 (patch) | |
tree | 06fa668c52f95cb1807ca07afa173fc796dbb0c6 /clang/tools/libclang/CIndexCodeCompletion.cpp | |
parent | 79418564458d28f8bbfa5259c2e541436bd866c6 (diff) | |
download | bcm5719-llvm-7dd96c23fd72e2be779857760c66788db0b51df8.tar.gz bcm5719-llvm-7dd96c23fd72e2be779857760c66788db0b51df8.zip |
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.
llvm-svn: 208454
Diffstat (limited to 'clang/tools/libclang/CIndexCodeCompletion.cpp')
-rw-r--r-- | clang/tools/libclang/CIndexCodeCompletion.cpp | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/clang/tools/libclang/CIndexCodeCompletion.cpp b/clang/tools/libclang/CIndexCodeCompletion.cpp index 23fdf93b76f..dbf54a1a8c1 100644 --- a/clang/tools/libclang/CIndexCodeCompletion.cpp +++ b/clang/tools/libclang/CIndexCodeCompletion.cpp @@ -255,6 +255,9 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults { /// \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::AllocatedCXCodeCompleteResults( } 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 *UserData) { *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(CXCodeCompleteResults *ResultsIn, 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 |