]> granicus.if.org Git - clang/commitdiff
[libclang] Add defensive checks to make sure we don't try to dereference
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sat, 10 Dec 2011 02:36:25 +0000 (02:36 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sat, 10 Dec 2011 02:36:25 +0000 (02:36 +0000)
a null pointer after getCursorDecl() is called. rdar://10298421.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146312 91177308-0d34-0410-b5e6-96231b3b80d8

tools/libclang/CIndex.cpp
tools/libclang/CIndexHigh.cpp
tools/libclang/CIndexUSRs.cpp
tools/libclang/CXCursor.cpp
tools/libclang/CXType.cpp

index e9a67dbfb5b77161ec5bb5e21bc914474aca668e..a0f6f686d6cff7f1ebcf02e419bbe56f442b90c7 100644 (file)
@@ -151,7 +151,11 @@ bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
 
   if (clang_isDeclaration(Cursor.kind)) {
     Decl *D = getCursorDecl(Cursor);
-    assert(D && "Invalid declaration cursor");
+    if (!D) {
+      assert(0 && "Invalid declaration cursor");
+      return true; // abort.
+    }
+    
     // Ignore implicit declarations, unless it's an objc method because
     // currently we should report implicit methods for properties when indexing.
     if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
@@ -2870,7 +2874,10 @@ unsigned clang_visitChildrenWithBlock(CXCursor parent,
 }
 
 static CXString getDeclSpelling(Decl *D) {
-  NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
+  if (!D)
+    return createCXString("");
+
+  NamedDecl *ND = dyn_cast<NamedDecl>(D);
   if (!ND) {
     if (ObjCPropertyImplDecl *PropImpl =dyn_cast<ObjCPropertyImplDecl>(D))
       if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
@@ -3420,23 +3427,23 @@ static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
   
   if (clang_isDeclaration(cursor.kind)) {
     // Avoid having the implicit methods override the property decls.
-    if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(getCursorDecl(cursor)))
+    if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor)))
       if (MD->isImplicit())
         return CXChildVisit_Break;
   }
 
   if (clang_isExpression(cursor.kind) &&
       clang_isDeclaration(BestCursor->kind)) {
-    Decl *D = getCursorDecl(*BestCursor);
-
-    // Avoid having the cursor of an expression replace the declaration cursor
-    // when the expression source range overlaps the declaration range.
-    // This can happen for C++ constructor expressions whose range generally
-    // include the variable declaration, e.g.:
-    //  MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
-    if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
-        D->getLocation() == Data->TokenBeginLoc)
-      return CXChildVisit_Break;
+    if (Decl *D = getCursorDecl(*BestCursor)) {
+      // Avoid having the cursor of an expression replace the declaration cursor
+      // when the expression source range overlaps the declaration range.
+      // This can happen for C++ constructor expressions whose range generally
+      // include the variable declaration, e.g.:
+      //  MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
+      if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
+          D->getLocation() == Data->TokenBeginLoc)
+        return CXChildVisit_Break;
+    }
   }
 
   // If our current best cursor is the construction of a temporary object, 
@@ -3682,6 +3689,9 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) {
     return clang_getNullLocation();
 
   Decl *D = getCursorDecl(C);
+  if (!D)
+    return clang_getNullLocation();
+
   SourceLocation Loc = D->getLocation();
   // FIXME: Multiple variables declared in a single declaration
   // currently lack the information needed to correctly determine their
@@ -3797,6 +3807,9 @@ static SourceRange getRawCursorExtent(CXCursor C) {
 
   if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
     Decl *D = cxcursor::getCursorDecl(C);
+    if (!D)
+      return SourceRange();
+
     SourceRange R = D->getSourceRange();
     // FIXME: Multiple variables declared in a single declaration
     // currently lack the information needed to correctly determine their
@@ -3817,6 +3830,9 @@ static SourceRange getRawCursorExtent(CXCursor C) {
 static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
   if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
     Decl *D = cxcursor::getCursorDecl(C);
+    if (!D)
+      return SourceRange();
+
     SourceRange R = D->getSourceRange();
 
     // Adjust the start of the location for declarations preceded by
@@ -3867,6 +3883,8 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
   CXTranslationUnit tu = getCursorTU(C);
   if (clang_isDeclaration(C.kind)) {
     Decl *D = getCursorDecl(C);
+    if (!D)
+      return clang_getNullCursor();
     if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
       return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
     if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
@@ -4768,10 +4786,10 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
     Decl *D = cxcursor::getCursorDecl(cursor);
     
     SourceLocation StartLoc;
-    if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
+    if (const DeclaratorDecl *DD = dyn_cast_or_null<DeclaratorDecl>(D)) {
       if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
         StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
-    } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
+    } else if (TypedefDecl *Typedef = dyn_cast_or_null<TypedefDecl>(D)) {
       if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
         StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
     }
@@ -5155,6 +5173,9 @@ CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
 //===----------------------------------------------------------------------===//
 
 static CXLanguageKind getDeclLanguage(const Decl *D) {
+  if (!D)
+    return CXLanguage_C;
+
   switch (D->getKind()) {
     default:
       break;
index 4eabefb9259c29d5bb33df6f6a21fa4bc8e06240..ec76898cc83b7a939aa78a6b4ec1dc8500e62f4a 100644 (file)
@@ -21,6 +21,8 @@ using namespace cxcursor;
 static void getTopOverriddenMethods(CXTranslationUnit TU,
                                     Decl *D,
                                     SmallVectorImpl<Decl *> &Methods) {
+  if (!D)
+    return;
   if (!isa<ObjCMethodDecl>(D) && !isa<CXXMethodDecl>(D))
     return;
 
@@ -147,6 +149,9 @@ static enum CXChildVisitResult findFileIdRefVisit(CXCursor cursor,
     return CXChildVisit_Recurse;
 
   Decl *D = cxcursor::getCursorDecl(declCursor);
+  if (!D)
+    return CXChildVisit_Continue;
+
   FindFileIdRefVisitData *data = (FindFileIdRefVisitData *)client_data;
   if (data->isHit(D)) {
     cursor = cxcursor::getSelectorIdentifierCursor(data->SelectorIdIdx, cursor);
index 32c4db6abecf08890429cde22951c523ecf121e6..40d4fb1c694642b2fa9d3283d07d58ffc91874fc 100644 (file)
@@ -845,6 +845,9 @@ CXString clang_getCursorUSR(CXCursor C) {
 
   if (clang_isDeclaration(K)) {
     Decl *D = cxcursor::getCursorDecl(C);
+    if (!D)
+      return createCXString("");
+
     CXTranslationUnit TU = cxcursor::getCursorTU(C);
     if (!TU)
       return createCXString("");
index 5117a4d2b3e6ae81c1db121754174fc5ee0339f2..1b8af395e2280de0ae6393dd8aa9441bfab8947f 100644 (file)
@@ -1019,8 +1019,7 @@ CXCompletionString clang_getCursorCompletionString(CXCursor cursor) {
   enum CXCursorKind kind = clang_getCursorKind(cursor);
   if (clang_isDeclaration(kind)) {
     Decl *decl = getCursorDecl(cursor);
-    if (isa<NamedDecl>(decl)) {
-      NamedDecl *namedDecl = (NamedDecl *)decl;
+    if (NamedDecl *namedDecl = dyn_cast_or_null<NamedDecl>(decl)) {
       ASTUnit *unit = getCursorASTUnit(cursor);
       if (unit->hasSema()) {
         Sema &S = unit->getSema();
index 8dcef4d1a820589b755b5d31516dfc272e707f11..52e77bda08e55f7d1577d60a80de1ff25d50e102 100644 (file)
@@ -123,6 +123,8 @@ CXType clang_getCursorType(CXCursor C) {
 
   if (clang_isDeclaration(C.kind)) {
     Decl *D = cxcursor::getCursorDecl(C);
+    if (!D)
+      return MakeCXType(QualType(), TU);
 
     if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
       return MakeCXType(Context.getTypeDeclType(TD), TU);
@@ -181,7 +183,7 @@ CXType clang_getTypedefDeclUnderlyingType(CXCursor C) {
   if (clang_isDeclaration(C.kind)) {
     Decl *D = cxcursor::getCursorDecl(C);
 
-    if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
+    if (TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) {
       QualType T = TD->getUnderlyingType();
       return MakeCXType(T, TU);
     }
@@ -199,7 +201,7 @@ CXType clang_getEnumDeclIntegerType(CXCursor C) {
   if (clang_isDeclaration(C.kind)) {
     Decl *D = cxcursor::getCursorDecl(C);
 
-    if (EnumDecl *TD = dyn_cast<EnumDecl>(D)) {
+    if (EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) {
       QualType T = TD->getIntegerType();
       return MakeCXType(T, TU);
     }
@@ -216,7 +218,7 @@ long long clang_getEnumConstantDeclValue(CXCursor C) {
   if (clang_isDeclaration(C.kind)) {
     Decl *D = cxcursor::getCursorDecl(C);
 
-    if (EnumConstantDecl *TD = dyn_cast<EnumConstantDecl>(D)) {
+    if (EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
       return TD->getInitVal().getSExtValue();
     }
 
@@ -232,7 +234,7 @@ unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) {
   if (clang_isDeclaration(C.kind)) {
     Decl *D = cxcursor::getCursorDecl(C);
 
-    if (EnumConstantDecl *TD = dyn_cast<EnumConstantDecl>(D)) {
+    if (EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
       return TD->getInitVal().getZExtValue();
     }
 
@@ -496,7 +498,7 @@ CXType clang_getResultType(CXType X) {
 CXType clang_getCursorResultType(CXCursor C) {
   if (clang_isDeclaration(C.kind)) {
     Decl *D = cxcursor::getCursorDecl(C);
-    if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
+    if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
       return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C));
 
     return clang_getResultType(clang_getCursorType(C));