[cfe-commits] r137887 - in /cfe/trunk/tools/libclang: CIndexCodeCompletion.cpp CXString.cpp CXString.h

Ted Kremenek kremenek at apple.com
Wed Aug 17 15:19:53 PDT 2011


Author: kremenek
Date: Wed Aug 17 17:19:53 2011
New Revision: 137887

URL: http://llvm.org/viewvc/llvm-project?rev=137887&view=rev
Log:
[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.

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

Modified: cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp?rev=137887&r1=137886&r2=137887&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp Wed Aug 17 17:19:53 2011
@@ -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 @@
         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();

Modified: cfe/trunk/tools/libclang/CXString.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXString.cpp?rev=137887&r1=137886&r2=137887&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXString.cpp (original)
+++ cfe/trunk/tools/libclang/CXString.cpp Wed Aug 17 17:19:53 2011
@@ -101,6 +101,10 @@
     static_cast<CXStringPool*>(buf->TU->StringPool)->push_back(buf);
 }
 
+bool cxstring::isManagedByPool(CXString str) {
+  return ((CXStringFlag) str.private_flags) == CXS_StringBuf;
+}
+
 //===----------------------------------------------------------------------===//
 // libClang public APIs.
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/tools/libclang/CXString.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXString.h?rev=137887&r1=137886&r2=137887&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXString.h (original)
+++ cfe/trunk/tools/libclang/CXString.h Wed Aug 17 17:19:53 2011
@@ -47,6 +47,9 @@
  
 void disposeCXStringBuf(CXStringBuf *buf);
 
+/// \brief Returns true if the CXString data is managed by a pool.
+bool isManagedByPool(CXString str);
+
 }
 }
 





More information about the cfe-commits mailing list