summaryrefslogtreecommitdiff
path: root/tools/libclang/CIndexCodeCompletion.cpp
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2014-05-09 22:33:11 +0000
committerNico Weber <nicolasweber@gmx.de>2014-05-09 22:33:11 +0000
commit3748941f2ea43eb81a4a8edf02abf7f83881fa89 (patch)
tree4a95b3d5e2c5edde8a3bc9391dc5b0e69701f0ae /tools/libclang/CIndexCodeCompletion.cpp
parentb8e405f9f3e00d9385239b0399b90b84d969e1e3 (diff)
downloadclang-3748941f2ea43eb81a4a8edf02abf7f83881fa89.tar.gz
clang-3748941f2ea43eb81a4a8edf02abf7f83881fa89.tar.bz2
clang-3748941f2ea43eb81a4a8edf02abf7f83881fa89.tar.xz
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@208454 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/libclang/CIndexCodeCompletion.cpp')
-rw-r--r--tools/libclang/CIndexCodeCompletion.cpp14
1 files changed, 12 insertions, 2 deletions
diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp
index 23fdf93b76..dbf54a1a8c 100644
--- a/tools/libclang/CIndexCodeCompletion.cpp
+++ b/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