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
This commit is contained in:
Douglas Gregor 2010-11-12 07:15:47 +00:00
Родитель 8f0889ce45
Коммит cb7b1e17b6
13 изменённых файлов: 103 добавлений и 49 удалений

Просмотреть файл

@ -724,6 +724,11 @@ public:
///
/// Note that a presumed location is always given as the instantiation point
/// of an instantiation location, not at the spelling location.
///
/// \returns The presumed location of the specified SourceLocation. If the
/// presumed location cannot be calculate (e.g., because \p Loc is invalid
/// or the file containing \p Loc has changed on disk), returns an invalid
/// presumed location.
PresumedLoc getPresumedLoc(SourceLocation Loc) const;
/// isFromSameFile - Returns true if both SourceLocations correspond to

Просмотреть файл

@ -169,15 +169,15 @@ namespace {
void StmtDumper::DumpLocation(SourceLocation Loc) {
SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
if (SpellingLoc.isInvalid()) {
OS << "<invalid sloc>";
return;
}
// The general format we print out is filename:line:col, but we drop pieces
// that haven't changed since the last loc printed.
PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
if (PLoc.isInvalid()) {
OS << "<invalid sloc>";
return;
}
if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
OS << PLoc.getFilename() << ':' << PLoc.getLine()
<< ':' << PLoc.getColumn();

Просмотреть файл

@ -481,9 +481,9 @@ void TypePrinter::PrintTag(TagDecl *D, std::string &InnerString) {
if (!HasKindDecoration)
OS << " " << D->getKindName();
if (D->getLocation().isValid()) {
PresumedLoc PLoc = D->getASTContext().getSourceManager().getPresumedLoc(
PresumedLoc PLoc = D->getASTContext().getSourceManager().getPresumedLoc(
D->getLocation());
if (PLoc.isValid()) {
OS << " at " << PLoc.getFilename()
<< ':' << PLoc.getLine()
<< ':' << PLoc.getColumn();

Просмотреть файл

@ -43,6 +43,11 @@ void SourceLocation::print(llvm::raw_ostream &OS, const SourceManager &SM)const{
if (isFileID()) {
PresumedLoc PLoc = SM.getPresumedLoc(*this);
if (PLoc.isInvalid()) {
OS << "<invalid>";
return;
}
// The instantiation and spelling pos is identical for file locs.
OS << PLoc.getFilename() << ':' << PLoc.getLine()
<< ':' << PLoc.getColumn();

Просмотреть файл

@ -143,19 +143,21 @@ public:
SourceManager &SM = Mgr->getASTContext().getSourceManager();
PresumedLoc Loc = SM.getPresumedLoc(D->getLocation());
llvm::errs() << "ANALYZE: " << Loc.getFilename();
if (Loc.isValid()) {
llvm::errs() << "ANALYZE: " << Loc.getFilename();
if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
const NamedDecl *ND = cast<NamedDecl>(D);
llvm::errs() << ' ' << ND << '\n';
}
else if (isa<BlockDecl>(D)) {
llvm::errs() << ' ' << "block(line:" << Loc.getLine() << ",col:"
<< Loc.getColumn() << '\n';
}
else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
Selector S = MD->getSelector();
llvm::errs() << ' ' << S.getAsString();
if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
const NamedDecl *ND = cast<NamedDecl>(D);
llvm::errs() << ' ' << ND << '\n';
}
else if (isa<BlockDecl>(D)) {
llvm::errs() << ' ' << "block(line:" << Loc.getLine() << ",col:"
<< Loc.getColumn() << '\n';
}
else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
Selector S = MD->getSelector();
llvm::errs() << ' ' << S.getAsString();
}
}
}

Просмотреть файл

@ -83,16 +83,18 @@ void AnalyzerStatsChecker::VisitEndAnalysis(ExplodedGraph &G,
llvm::SmallString<128> buf;
llvm::raw_svector_ostream output(buf);
PresumedLoc Loc = SM.getPresumedLoc(D->getLocation());
output << Loc.getFilename() << " : ";
if (Loc.isValid()) {
output << Loc.getFilename() << " : ";
if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
const NamedDecl *ND = cast<NamedDecl>(D);
output << ND;
if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
const NamedDecl *ND = cast<NamedDecl>(D);
output << ND;
}
else if (isa<BlockDecl>(D)) {
output << "block(line:" << Loc.getLine() << ":col:" << Loc.getColumn();
}
}
else if (isa<BlockDecl>(D)) {
output << "block(line:" << Loc.getLine() << ":col:" << Loc.getColumn();
}
output << " -> Total CFGBlocks: " << total << " | Unreachable CFGBlocks: "
<< unreachable << " | Aborted Block: "
<< (Eng.wasBlockAborted() ? "yes" : "no")

Просмотреть файл

@ -327,9 +327,11 @@ PresumedLoc DocumentXML::addLocation(const SourceLocation& Loc)
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 @@ void DocumentXML::addLocationRange(const SourceRange& R)
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());

Просмотреть файл

@ -131,7 +131,10 @@ public:
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 @@ void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc,
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 @@ void clang::DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream *OS,
// 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);

Просмотреть файл

@ -57,7 +57,9 @@ PrintIncludeStack(SourceLocation Loc, const SourceManager &SM) {
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 @@ void TextDiagnosticPrinter::EmitCaretDiagnostic(SourceLocation Loc,
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 @@ void TextDiagnosticPrinter::EmitCaretDiagnostic(SourceLocation Loc,
// 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 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level,
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

Просмотреть файл

@ -804,7 +804,9 @@ static bool ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit,
FileID CurFileID =
SM.getDecomposedInstantiationLoc(FlagTok.getLocation()).first;
PresumedLoc PLoc = SM.getPresumedLoc(FlagTok.getLocation());
if (PLoc.isInvalid())
return true;
// If there is no include loc (main file) or if the include loc is in a
// different physical file, then we aren't in a "1" line marker flag region.
SourceLocation IncLoc = PLoc.getIncludeLoc();

Просмотреть файл

@ -723,7 +723,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
PresumedLoc PLoc = SourceMgr.getPresumedLoc(Loc);
// __LINE__ expands to a simple numeric value.
OS << PLoc.getLine();
OS << (PLoc.isValid()? PLoc.getLine() : 1);
Tok.setKind(tok::numeric_constant);
} else if (II == Ident__FILE__ || II == Ident__BASE_FILE__) {
// C99 6.10.8: "__FILE__: The presumed name of the current source file (a
@ -732,19 +732,24 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
// __BASE_FILE__ is a GNU extension that returns the top of the presumed
// #include stack instead of the current file.
if (II == Ident__BASE_FILE__) {
if (II == Ident__BASE_FILE__ && PLoc.isValid()) {
SourceLocation NextLoc = PLoc.getIncludeLoc();
while (NextLoc.isValid()) {
PLoc = SourceMgr.getPresumedLoc(NextLoc);
if (PLoc.isInvalid())
break;
NextLoc = PLoc.getIncludeLoc();
}
}
// Escape this filename. Turn '\' -> '\\' '"' -> '\"'
llvm::SmallString<128> FN;
FN += PLoc.getFilename();
Lexer::Stringify(FN);
OS << '"' << FN.str() << '"';
if (PLoc.isValid()) {
FN += PLoc.getFilename();
Lexer::Stringify(FN);
OS << '"' << FN.str() << '"';
}
Tok.setKind(tok::string_literal);
} else if (II == Ident__DATE__) {
if (!DATELoc.isValid())
@ -770,9 +775,11 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
unsigned Depth = 0;
PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation());
PLoc = SourceMgr.getPresumedLoc(PLoc.getIncludeLoc());
for (; PLoc.isValid(); ++Depth)
if (PLoc.isValid()) {
PLoc = SourceMgr.getPresumedLoc(PLoc.getIncludeLoc());
for (; PLoc.isValid(); ++Depth)
PLoc = SourceMgr.getPresumedLoc(PLoc.getIncludeLoc());
}
// __INCLUDE_LEVEL__ expands to a simple numeric value.
OS << Depth;

Просмотреть файл

@ -329,6 +329,9 @@ void Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {
PresumedLoc PLoc = SourceMgr.getPresumedLoc(SysHeaderTok.getLocation());
if (PLoc.isInvalid())
return;
unsigned FilenameLen = strlen(PLoc.getFilename());
unsigned FilenameID = SourceMgr.getLineTableFilenameID(PLoc.getFilename(),
FilenameLen);

Просмотреть файл

@ -55,7 +55,7 @@ void clang_getInclusions(CXTranslationUnit TU, CXInclusionVisitor CB,
while (L.isValid()) {
PresumedLoc PLoc = SM.getPresumedLoc(L);
InclusionStack.push_back(cxloc::translateSourceLocation(Ctx, L));
L = PLoc.getIncludeLoc();
L = PLoc.isValid()? PLoc.getIncludeLoc() : SourceLocation();
}
// Callback to the client.