2011-08-13 07:04:46 +08:00
|
|
|
//==- ProgramPoint.cpp - Program Points for Path-Sensitive Analysis -*- C++ -*-/
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2011-08-13 07:04:46 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file defines the interface ProgramPoint, which identifies a
|
|
|
|
// distinct location in a function.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "clang/Analysis/ProgramPoint.h"
|
|
|
|
|
|
|
|
using namespace clang;
|
|
|
|
|
2015-10-20 21:23:58 +08:00
|
|
|
ProgramPointTag::~ProgramPointTag() {}
|
2011-08-13 07:04:46 +08:00
|
|
|
|
2011-10-08 05:01:38 +08:00
|
|
|
ProgramPoint ProgramPoint::getProgramPoint(const Stmt *S, ProgramPoint::Kind K,
|
|
|
|
const LocationContext *LC,
|
|
|
|
const ProgramPointTag *tag){
|
|
|
|
switch (K) {
|
|
|
|
default:
|
|
|
|
llvm_unreachable("Unhandled ProgramPoint kind");
|
|
|
|
case ProgramPoint::PreStmtKind:
|
|
|
|
return PreStmt(S, LC, tag);
|
|
|
|
case ProgramPoint::PostStmtKind:
|
|
|
|
return PostStmt(S, LC, tag);
|
|
|
|
case ProgramPoint::PreLoadKind:
|
|
|
|
return PreLoad(S, LC, tag);
|
|
|
|
case ProgramPoint::PostLoadKind:
|
|
|
|
return PostLoad(S, LC, tag);
|
|
|
|
case ProgramPoint::PreStoreKind:
|
|
|
|
return PreStore(S, LC, tag);
|
|
|
|
case ProgramPoint::PostLValueKind:
|
|
|
|
return PostLValue(S, LC, tag);
|
2012-04-21 05:59:08 +08:00
|
|
|
case ProgramPoint::PostStmtPurgeDeadSymbolsKind:
|
|
|
|
return PostStmtPurgeDeadSymbols(S, LC, tag);
|
|
|
|
case ProgramPoint::PreStmtPurgeDeadSymbolsKind:
|
|
|
|
return PreStmtPurgeDeadSymbols(S, LC, tag);
|
2011-10-08 05:01:38 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-01 02:05:39 +08:00
|
|
|
LLVM_DUMP_METHOD void ProgramPoint::dump() const {
|
|
|
|
return print(/*CR=*/"\n", llvm::errs());
|
|
|
|
}
|
|
|
|
|
2018-09-27 09:46:18 +08:00
|
|
|
static void printLocation(raw_ostream &Out, SourceLocation SLoc,
|
|
|
|
const SourceManager &SM,
|
|
|
|
StringRef CR,
|
|
|
|
StringRef Postfix) {
|
|
|
|
if (SLoc.isFileID()) {
|
|
|
|
Out << CR << "line=" << SM.getExpansionLineNumber(SLoc)
|
|
|
|
<< " col=" << SM.getExpansionColumnNumber(SLoc) << Postfix;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProgramPoint::print(StringRef CR, llvm::raw_ostream &Out) const {
|
|
|
|
const ASTContext &Context =
|
|
|
|
getLocationContext()->getAnalysisDeclContext()->getASTContext();
|
|
|
|
const SourceManager &SM = Context.getSourceManager();
|
|
|
|
switch (getKind()) {
|
|
|
|
case ProgramPoint::BlockEntranceKind:
|
|
|
|
Out << "Block Entrance: B"
|
|
|
|
<< castAs<BlockEntrance>().getBlock()->getBlockID();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ProgramPoint::FunctionExitKind: {
|
|
|
|
auto FEP = getAs<FunctionExitPoint>();
|
|
|
|
Out << "Function Exit: B" << FEP->getBlock()->getBlockID();
|
|
|
|
if (const ReturnStmt *RS = FEP->getStmt()) {
|
|
|
|
Out << CR << " Return: S" << RS->getID(Context) << CR;
|
|
|
|
RS->printPretty(Out, /*helper=*/nullptr, Context.getPrintingPolicy(),
|
|
|
|
/*Indentation=*/2, /*NewlineSymbol=*/CR);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ProgramPoint::BlockExitKind:
|
|
|
|
assert(false);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ProgramPoint::CallEnterKind:
|
|
|
|
Out << "CallEnter";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ProgramPoint::CallExitBeginKind:
|
|
|
|
Out << "CallExitBegin";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ProgramPoint::CallExitEndKind:
|
|
|
|
Out << "CallExitEnd";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ProgramPoint::PostStmtPurgeDeadSymbolsKind:
|
|
|
|
Out << "PostStmtPurgeDeadSymbols";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ProgramPoint::PreStmtPurgeDeadSymbolsKind:
|
|
|
|
Out << "PreStmtPurgeDeadSymbols";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ProgramPoint::EpsilonKind:
|
|
|
|
Out << "Epsilon Point";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ProgramPoint::LoopExitKind: {
|
|
|
|
LoopExit LE = castAs<LoopExit>();
|
|
|
|
Out << "LoopExit: " << LE.getLoopStmt()->getStmtClassName();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ProgramPoint::PreImplicitCallKind: {
|
|
|
|
ImplicitCallPoint PC = castAs<ImplicitCallPoint>();
|
|
|
|
Out << "PreCall: ";
|
|
|
|
PC.getDecl()->print(Out, Context.getLangOpts());
|
|
|
|
printLocation(Out, PC.getLocation(), SM, CR, /*Postfix=*/CR);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ProgramPoint::PostImplicitCallKind: {
|
|
|
|
ImplicitCallPoint PC = castAs<ImplicitCallPoint>();
|
|
|
|
Out << "PostCall: ";
|
|
|
|
PC.getDecl()->print(Out, Context.getLangOpts());
|
|
|
|
printLocation(Out, PC.getLocation(), SM, CR, /*Postfix=*/CR);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ProgramPoint::PostInitializerKind: {
|
|
|
|
Out << "PostInitializer: ";
|
|
|
|
const CXXCtorInitializer *Init = castAs<PostInitializer>().getInitializer();
|
|
|
|
if (const FieldDecl *FD = Init->getAnyMember())
|
|
|
|
Out << *FD;
|
|
|
|
else {
|
|
|
|
QualType Ty = Init->getTypeSourceInfo()->getType();
|
|
|
|
Ty = Ty.getLocalUnqualifiedType();
|
|
|
|
Ty.print(Out, Context.getLangOpts());
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ProgramPoint::BlockEdgeKind: {
|
|
|
|
const BlockEdge &E = castAs<BlockEdge>();
|
|
|
|
Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
|
|
|
|
<< E.getDst()->getBlockID() << ')';
|
|
|
|
|
|
|
|
if (const Stmt *T = E.getSrc()->getTerminator()) {
|
|
|
|
SourceLocation SLoc = T->getBeginLoc();
|
|
|
|
|
|
|
|
Out << "\\|Terminator: ";
|
|
|
|
E.getSrc()->printTerminator(Out, Context.getLangOpts());
|
|
|
|
printLocation(Out, SLoc, SM, CR, /*Postfix=*/"");
|
|
|
|
|
|
|
|
if (isa<SwitchStmt>(T)) {
|
|
|
|
const Stmt *Label = E.getDst()->getLabel();
|
|
|
|
|
|
|
|
if (Label) {
|
|
|
|
if (const auto *C = dyn_cast<CaseStmt>(Label)) {
|
|
|
|
Out << CR << "case ";
|
|
|
|
if (C->getLHS())
|
|
|
|
C->getLHS()->printPretty(
|
|
|
|
Out, nullptr, Context.getPrintingPolicy(),
|
|
|
|
/*Indentation=*/0, /*NewlineSymbol=*/CR);
|
|
|
|
|
|
|
|
if (const Stmt *RHS = C->getRHS()) {
|
|
|
|
Out << " .. ";
|
|
|
|
RHS->printPretty(Out, nullptr, Context.getPrintingPolicy(),
|
|
|
|
/*Indetation=*/0, /*NewlineSymbol=*/CR);
|
|
|
|
}
|
|
|
|
|
|
|
|
Out << ":";
|
|
|
|
} else {
|
|
|
|
assert(isa<DefaultStmt>(Label));
|
|
|
|
Out << CR << "default:";
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
Out << CR << "(implicit) default:";
|
|
|
|
} else if (isa<IndirectGotoStmt>(T)) {
|
|
|
|
// FIXME
|
|
|
|
} else {
|
|
|
|
Out << CR << "Condition: ";
|
|
|
|
if (*E.getSrc()->succ_begin() == E.getDst())
|
|
|
|
Out << "true";
|
|
|
|
else
|
|
|
|
Out << "false";
|
|
|
|
}
|
|
|
|
|
|
|
|
Out << CR;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
default: {
|
|
|
|
const Stmt *S = castAs<StmtPoint>().getStmt();
|
|
|
|
assert(S != nullptr && "Expecting non-null Stmt");
|
|
|
|
|
|
|
|
Out << S->getStmtClassName() << " S" << S->getID(Context) << " <"
|
|
|
|
<< (const void *)S << "> ";
|
|
|
|
S->printPretty(Out, /*helper=*/nullptr, Context.getPrintingPolicy(),
|
|
|
|
/*Indentation=*/2, /*NewlineSymbol=*/CR);
|
|
|
|
printLocation(Out, S->getBeginLoc(), SM, CR, /*Postfix=*/"");
|
|
|
|
|
|
|
|
if (getAs<PreStmt>())
|
|
|
|
Out << CR << "PreStmt" << CR;
|
|
|
|
else if (getAs<PostLoad>())
|
|
|
|
Out << CR << "PostLoad" << CR;
|
|
|
|
else if (getAs<PostStore>())
|
|
|
|
Out << CR << "PostStore" << CR;
|
|
|
|
else if (getAs<PostLValue>())
|
|
|
|
Out << CR << "PostLValue" << CR;
|
|
|
|
else if (getAs<PostAllocatorCall>())
|
|
|
|
Out << CR << "PostAllocatorCall" << CR;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-31 03:24:48 +08:00
|
|
|
SimpleProgramPointTag::SimpleProgramPointTag(StringRef MsgProvider,
|
2014-02-18 02:25:34 +08:00
|
|
|
StringRef Msg)
|
|
|
|
: Desc((MsgProvider + " : " + Msg).str()) {}
|
2011-08-13 07:04:46 +08:00
|
|
|
|
|
|
|
StringRef SimpleProgramPointTag::getTagDescription() const {
|
2014-02-18 02:25:34 +08:00
|
|
|
return Desc;
|
2011-08-13 07:04:46 +08:00
|
|
|
}
|