Make sure to always check the result of
SourceManager::getPresumedLoc(), so that we don't try to make use of
an invalid presumed location. Doing so can cause crashes.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118885 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Frontend/DocumentXML.cpp b/lib/Frontend/DocumentXML.cpp
index 2f7e995..b24ece5 100644
--- a/lib/Frontend/DocumentXML.cpp
+++ b/lib/Frontend/DocumentXML.cpp
@@ -327,9 +327,11 @@
   if (!SpellingLoc.isInvalid())
   {
     PLoc = SM.getPresumedLoc(SpellingLoc);
-    addSourceFileAttribute(PLoc.getFilename());
-    addAttribute("line", PLoc.getLine());
-    addAttribute("col", PLoc.getColumn());
+    if (PLoc.isValid()) {
+      addSourceFileAttribute(PLoc.getFilename());
+      addAttribute("line", PLoc.getLine());
+      addAttribute("col", PLoc.getColumn());
+    }
   }
   // else there is no error in some cases (eg. CXXThisExpr)
   return PLoc;
@@ -346,8 +348,9 @@
     if (!SpellingLoc.isInvalid())
     {
       PresumedLoc PLoc = SM.getPresumedLoc(SpellingLoc);
-      if (PStartLoc.isInvalid() ||
-          strcmp(PLoc.getFilename(), PStartLoc.getFilename()) != 0) {
+      if (PLoc.isInvalid()) {
+      } else if (PStartLoc.isInvalid() ||
+                 strcmp(PLoc.getFilename(), PStartLoc.getFilename()) != 0) {
         addToMap(SourceFiles, PLoc.getFilename(), ID_FILE);
         addAttribute("endfile", PLoc.getFilename());
         addAttribute("endline", PLoc.getLine());
diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp
index 6019b30..429999c 100644
--- a/lib/Frontend/PrintPreprocessedOutput.cpp
+++ b/lib/Frontend/PrintPreprocessedOutput.cpp
@@ -131,7 +131,10 @@
 
   bool HandleFirstTokOnLine(Token &Tok);
   bool MoveToLine(SourceLocation Loc) {
-    return MoveToLine(SM.getPresumedLoc(Loc).getLine());
+    PresumedLoc PLoc = SM.getPresumedLoc(Loc);
+    if (PLoc.isInvalid())
+      return false;
+    return MoveToLine(PLoc.getLine());
   }
   bool MoveToLine(unsigned LineNo);
 
@@ -238,10 +241,13 @@
   SourceManager &SourceMgr = SM;
   
   PresumedLoc UserLoc = SourceMgr.getPresumedLoc(Loc);
+  if (UserLoc.isInvalid())
+    return;
+  
   unsigned NewLine = UserLoc.getLine();
 
   if (Reason == PPCallbacks::EnterFile) {
-    SourceLocation IncludeLoc = SourceMgr.getPresumedLoc(Loc).getIncludeLoc();
+    SourceLocation IncludeLoc = UserLoc.getIncludeLoc();
     if (IncludeLoc.isValid())
       MoveToLine(IncludeLoc);
   } else if (Reason == PPCallbacks::SystemHeaderPragma) {
@@ -593,10 +599,18 @@
   // start.
   const SourceManager &SourceMgr = PP.getSourceManager();
   Token Tok;
-  do PP.Lex(Tok);
-  while (Tok.isNot(tok::eof) && Tok.getLocation().isFileID() &&
-         !strcmp(SourceMgr.getPresumedLoc(Tok.getLocation()).getFilename(),
-                 "<built-in>"));
+  do {
+    PP.Lex(Tok);
+    if (Tok.is(tok::eof) || !Tok.getLocation().isFileID())
+      break;
+
+    PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation());
+    if (PLoc.isInvalid())
+      break;
+
+    if (strcmp(PLoc.getFilename(), "<built-in>"))
+      break;
+  } while (true);
 
   // Read all the preprocessed tokens, printing them out to the stream.
   PrintPreprocessedTokens(PP, Tok, Callbacks, *OS);
diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp
index 9e450d2..4fd0552 100644
--- a/lib/Frontend/TextDiagnosticPrinter.cpp
+++ b/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -57,7 +57,9 @@
   if (Loc.isInvalid()) return;
 
   PresumedLoc PLoc = SM.getPresumedLoc(Loc);
-
+  if (PLoc.isInvalid())
+    return;
+  
   // Print out the other include frames first.
   PrintIncludeStack(PLoc.getIncludeLoc(), SM);
 
@@ -328,7 +330,9 @@
     if (!Suppressed) {
       // Get the pretty name, according to #line directives etc.
       PresumedLoc PLoc = SM.getPresumedLoc(Loc);
-
+      if (PLoc.isInvalid())
+        return;
+      
       // If this diagnostic is not in the main file, print out the
       // "included from" lines.
       if (LastWarningLoc != PLoc.getIncludeLoc()) {
@@ -567,6 +571,10 @@
 
         // We specifically do not do word-wrapping or tab-expansion here,
         // because this is supposed to be easy to parse.
+        PresumedLoc PLoc = SM.getPresumedLoc(B);
+        if (PLoc.isInvalid())
+          break;
+        
         OS << "fix-it:\"";
         OS.write_escaped(SM.getPresumedLoc(B).getFilename());
         OS << "\":{" << SM.getLineNumber(BInfo.first, BInfo.second)
@@ -770,6 +778,9 @@
   if (Info.getLocation().isValid()) {
     const SourceManager &SM = Info.getLocation().getManager();
     PresumedLoc PLoc = SM.getPresumedLoc(Info.getLocation());
+    if (PLoc.isInvalid())
+      return;
+    
     unsigned LineNo = PLoc.getLine();
 
     // First, if this diagnostic is not in the main file, print out the