diff options
author | Ted Kremenek <kremenek@apple.com> | 2011-03-23 02:16:44 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2011-03-23 02:16:44 +0000 |
commit | 9d5a165d301cc9df68631e624322dd2a962f65b3 (patch) | |
tree | a9e0dc6d2b632a94a942afdb970780a6fa6997b1 | |
parent | 114d63955f8d55e4c2f0350abf907fbb5eeeb08b (diff) |
Fix crash in clang_getInstantiationLoc() when SourceManager::getInstantiationLoc() can return a SourceLocatin with an invalid
FileID on invalid code. Fixes <rdar://problem/9164623>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128139 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/SourceManager.h | 6 | ||||
-rw-r--r-- | tools/libclang/CIndex.cpp | 35 |
2 files changed, 32 insertions, 9 deletions
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index 4c8a805538..260092536e 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -585,6 +585,12 @@ public: return getSLocEntry(FID).getFile().getContentCache()->OrigEntry; } + /// Returns the FileEntry record for the provided SLocEntry. + const FileEntry *getFileEntryForSLocEntry(const SrcMgr::SLocEntry &sloc) const + { + return sloc.getFile().getContentCache()->OrigEntry; + } + /// getBufferData - Return a StringRef to the source buffer data for the /// specified FileID. /// diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index b12e7fe41e..0978f1b281 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -2718,7 +2718,22 @@ CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) { begin.int_data, end.int_data }; return Result; } +} // end: extern "C" + +static void createNullLocation(CXFile *file, unsigned *line, + unsigned *column, unsigned *offset) { + if (file) + *file = 0; + if (line) + *line = 0; + if (column) + *column = 0; + if (offset) + *offset = 0; + return; +} +extern "C" { void clang_getInstantiationLocation(CXSourceLocation location, CXFile *file, unsigned *line, @@ -2727,14 +2742,7 @@ void clang_getInstantiationLocation(CXSourceLocation location, SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data); if (!location.ptr_data[0] || Loc.isInvalid()) { - if (file) - *file = 0; - if (line) - *line = 0; - if (column) - *column = 0; - if (offset) - *offset = 0; + createNullLocation(file, line, column, offset); return; } @@ -2742,8 +2750,17 @@ void clang_getInstantiationLocation(CXSourceLocation location, *static_cast<const SourceManager*>(location.ptr_data[0]); SourceLocation InstLoc = SM.getInstantiationLoc(Loc); + // Check that the FileID is invalid on the instantiation location. + // This can manifest in invalid code. + FileID fileID = SM.getFileID(InstLoc); + const SrcMgr::SLocEntry &sloc = SM.getSLocEntry(fileID); + if (!sloc.isFile()) { + createNullLocation(file, line, column, offset); + return; + } + if (file) - *file = (void *)SM.getFileEntryForID(SM.getFileID(InstLoc)); + *file = (void *)SM.getFileEntryForSLocEntry(sloc); if (line) *line = SM.getInstantiationLineNumber(InstLoc); if (column) |