From 16ed0e6fda74800595cb98d11969fc4afcc00bac Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Sat, 10 Dec 2011 02:36:25 +0000 Subject: [PATCH] [libclang] Add defensive checks to make sure we don't try to dereference 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 | 51 ++++++++++++++++++++++++----------- tools/libclang/CIndexHigh.cpp | 5 ++++ tools/libclang/CIndexUSRs.cpp | 3 +++ tools/libclang/CXCursor.cpp | 3 +-- tools/libclang/CXType.cpp | 12 +++++---- 5 files changed, 52 insertions(+), 22 deletions(-) diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index e9a67dbfb5..a0f6f686d6 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -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(D)) @@ -2870,7 +2874,10 @@ unsigned clang_visitChildrenWithBlock(CXCursor parent, } static CXString getDeclSpelling(Decl *D) { - NamedDecl *ND = dyn_cast_or_null(D); + if (!D) + return createCXString(""); + + NamedDecl *ND = dyn_cast(D); if (!ND) { if (ObjCPropertyImplDecl *PropImpl =dyn_cast(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(getCursorDecl(cursor))) + if (ObjCMethodDecl *MD = dyn_cast_or_null(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(D)) return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu); if (ObjCClassDecl *Classes = dyn_cast(D)) @@ -4768,10 +4786,10 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) { Decl *D = cxcursor::getCursorDecl(cursor); SourceLocation StartLoc; - if (const DeclaratorDecl *DD = dyn_cast(D)) { + if (const DeclaratorDecl *DD = dyn_cast_or_null(D)) { if (TypeSourceInfo *TI = DD->getTypeSourceInfo()) StartLoc = TI->getTypeLoc().getSourceRange().getBegin(); - } else if (TypedefDecl *Typedef = dyn_cast(D)) { + } else if (TypedefDecl *Typedef = dyn_cast_or_null(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; diff --git a/tools/libclang/CIndexHigh.cpp b/tools/libclang/CIndexHigh.cpp index 4eabefb925..ec76898cc8 100644 --- a/tools/libclang/CIndexHigh.cpp +++ b/tools/libclang/CIndexHigh.cpp @@ -21,6 +21,8 @@ using namespace cxcursor; static void getTopOverriddenMethods(CXTranslationUnit TU, Decl *D, SmallVectorImpl &Methods) { + if (!D) + return; if (!isa(D) && !isa(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); diff --git a/tools/libclang/CIndexUSRs.cpp b/tools/libclang/CIndexUSRs.cpp index 32c4db6abe..40d4fb1c69 100644 --- a/tools/libclang/CIndexUSRs.cpp +++ b/tools/libclang/CIndexUSRs.cpp @@ -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(""); diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp index 5117a4d2b3..1b8af395e2 100644 --- a/tools/libclang/CXCursor.cpp +++ b/tools/libclang/CXCursor.cpp @@ -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(decl)) { - NamedDecl *namedDecl = (NamedDecl *)decl; + if (NamedDecl *namedDecl = dyn_cast_or_null(decl)) { ASTUnit *unit = getCursorASTUnit(cursor); if (unit->hasSema()) { Sema &S = unit->getSema(); diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp index 8dcef4d1a8..52e77bda08 100644 --- a/tools/libclang/CXType.cpp +++ b/tools/libclang/CXType.cpp @@ -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(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(D)) { + if (TypedefNameDecl *TD = dyn_cast_or_null(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(D)) { + if (EnumDecl *TD = dyn_cast_or_null(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(D)) { + if (EnumConstantDecl *TD = dyn_cast_or_null(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(D)) { + if (EnumConstantDecl *TD = dyn_cast_or_null(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(D)) + if (const ObjCMethodDecl *MD = dyn_cast_or_null(D)) return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C)); return clang_getResultType(clang_getCursorType(C)); -- 2.40.0