diff options
author | Ted Kremenek <kremenek@apple.com> | 2011-08-17 22:19:53 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2011-08-17 22:19:53 +0000 |
commit | 5b8ad40664b947f752bf567af99df08e6691bef6 (patch) | |
tree | b254f2c733e3e0e87db25f0c02f2e27755a78444 /clang/tools/libclang/CIndexCodeCompletion.cpp | |
parent | c482a1929490ca2bcba5060d99a06b06bf3edac9 (diff) | |
download | bcm5719-llvm-5b8ad40664b947f752bf567af99df08e6691bef6.tar.gz bcm5719-llvm-5b8ad40664b947f752bf567af99df08e6691bef6.zip |
[libclang] Workaround potential race condition with code completion AllocatedResults being freed after a CXTranslationUnit.
The Container USR's CXString had its underlying data owned by the CXTranslationUnit's string pool. This
would result in trying to access freed memory.
llvm-svn: 137887
Diffstat (limited to 'clang/tools/libclang/CIndexCodeCompletion.cpp')
-rw-r--r-- | clang/tools/libclang/CIndexCodeCompletion.cpp | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/clang/tools/libclang/CIndexCodeCompletion.cpp b/clang/tools/libclang/CIndexCodeCompletion.cpp index 93571e0c350..21592989890 100644 --- a/clang/tools/libclang/CIndexCodeCompletion.cpp +++ b/clang/tools/libclang/CIndexCodeCompletion.cpp @@ -16,6 +16,7 @@ #include "CXTranslationUnit.h" #include "CXString.h" #include "CXCursor.h" +#include "CXString.h" #include "CIndexDiagnostic.h" #include "clang/AST/Type.h" #include "clang/AST/Decl.h" @@ -541,8 +542,20 @@ namespace { CXCursorKind cursorKind = clang_getCursorKind(cursor); CXString cursorUSR = clang_getCursorUSR(cursor); + // Normally, clients of CXString shouldn't care whether or not + // a CXString is managed by a pool or by explicitly malloc'ed memory. + // However, there are cases when AllocatedResults outlives the + // CXTranslationUnit. This is a workaround that failure mode. + if (cxstring::isManagedByPool(cursorUSR)) { + CXString heapStr = + cxstring::createCXString(clang_getCString(cursorUSR), true); + clang_disposeString(cursorUSR); + cursorUSR = heapStr; + } + AllocatedResults.ContainerKind = cursorKind; AllocatedResults.ContainerUSR = cursorUSR; + const Type *type = baseType.getTypePtrOrNull(); if (type != NULL) { AllocatedResults.ContainerIsIncomplete = type->isIncompleteType(); |