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
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index b12e7fe..0978f1b 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -2718,7 +2718,22 @@
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 @@
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 @@
*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)