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
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user