aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2011-03-23 02:16:44 +0000
committerTed Kremenek <kremenek@apple.com>2011-03-23 02:16:44 +0000
commit9d5a165d301cc9df68631e624322dd2a962f65b3 (patch)
treea9e0dc6d2b632a94a942afdb970780a6fa6997b1
parent114d63955f8d55e4c2f0350abf907fbb5eeeb08b (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.h6
-rw-r--r--tools/libclang/CIndex.cpp35
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)