forked from OSchip/llvm-project
get a CodeTextRegion when visiting FunctionDecl reference.
get FunctionDecl with more general utility method. llvm-svn: 69570
This commit is contained in:
parent
6840825137
commit
ac1294318d
|
@ -39,11 +39,11 @@ class MemRegionManager;
|
|||
class MemRegion : public llvm::FoldingSetNode {
|
||||
public:
|
||||
enum Kind { MemSpaceRegionKind,
|
||||
CodeTextRegionKind,
|
||||
SymbolicRegionKind,
|
||||
AllocaRegionKind,
|
||||
// Typed regions.
|
||||
BEG_TYPED_REGIONS,
|
||||
CodeTextRegionKind,
|
||||
CompoundLiteralRegionKind,
|
||||
StringRegionKind, ElementRegionKind,
|
||||
TypedViewRegionKind,
|
||||
|
@ -215,6 +215,13 @@ public:
|
|||
QualType getLValueType(ASTContext &C) const {
|
||||
return LocationType;
|
||||
}
|
||||
|
||||
bool isDeclared() const { return codekind == Declared; }
|
||||
|
||||
const FunctionDecl* getDecl() const {
|
||||
assert(codekind == Declared);
|
||||
return static_cast<const FunctionDecl*>(Data);
|
||||
}
|
||||
|
||||
virtual bool isBoundable(ASTContext&) const { return false; }
|
||||
|
||||
|
|
|
@ -89,6 +89,11 @@ public:
|
|||
}
|
||||
|
||||
bool isZeroConstant() const;
|
||||
|
||||
/// getAsFunctionDecl - If this SVal is a MemRegionVal and wraps a
|
||||
/// CodeTextRegion wrapping a FunctionDecl, return that FunctionDecl.
|
||||
/// Otherwise return 0.
|
||||
const FunctionDecl* getAsFunctionDecl() const;
|
||||
|
||||
/// getAsLocSymbol - If this SVal is a location (subclasses Loc) and
|
||||
/// wraps a symbol, return that SymbolRef. Otherwise return a SymbolData*
|
||||
|
|
|
@ -375,9 +375,9 @@ bool AuditCFNumberCreate::Audit(ExplodedNode<GRState>* N,GRStateManager&){
|
|||
CallExpr* CE = cast<CallExpr>(cast<PostStmt>(N->getLocation()).getStmt());
|
||||
Expr* Callee = CE->getCallee();
|
||||
SVal CallV = GetSVal(N->getState(), Callee);
|
||||
loc::FuncVal* FuncV = dyn_cast<loc::FuncVal>(&CallV);
|
||||
const FunctionDecl* FD = CallV.getAsFunctionDecl();
|
||||
|
||||
if (!FuncV || FuncV->getDecl()->getIdentifier() != II || CE->getNumArgs()!=3)
|
||||
if (!FD || FD->getIdentifier() != II || CE->getNumArgs()!=3)
|
||||
return false;
|
||||
|
||||
// Get the value of the "theType" argument.
|
||||
|
|
|
@ -1694,7 +1694,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
|
|||
Expr* Ex,
|
||||
Expr* Receiver,
|
||||
RetainSummary* Summ,
|
||||
ExprIterator arg_beg, ExprIterator arg_end,
|
||||
ExprIterator arg_beg, ExprIterator arg_end,
|
||||
ExplodedNode<GRState>* Pred) {
|
||||
|
||||
// Get the state.
|
||||
|
@ -1930,9 +1930,9 @@ void CFRefCount::EvalCall(ExplodedNodeSet<GRState>& Dst,
|
|||
GRStmtNodeBuilder<GRState>& Builder,
|
||||
CallExpr* CE, SVal L,
|
||||
ExplodedNode<GRState>* Pred) {
|
||||
|
||||
RetainSummary* Summ = !isa<loc::FuncVal>(L) ? 0
|
||||
: Summaries.getSummary(cast<loc::FuncVal>(L).getDecl());
|
||||
const FunctionDecl* FD = L.getAsFunctionDecl();
|
||||
RetainSummary* Summ = !FD ? 0
|
||||
: Summaries.getSummary(const_cast<FunctionDecl*>(FD));
|
||||
|
||||
EvalSummary(Dst, Eng, Builder, CE, 0, Summ,
|
||||
CE->arg_begin(), CE->arg_end(), Pred);
|
||||
|
@ -2582,9 +2582,9 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode<GRState>* N,
|
|||
|
||||
if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
|
||||
// Get the name of the callee (if it is available).
|
||||
SVal X = CurrSt.GetSValAsScalarOrLoc(CE->getCallee());
|
||||
if (loc::FuncVal* FV = dyn_cast<loc::FuncVal>(&X))
|
||||
os << "Call to function '" << FV->getDecl()->getNameAsString() <<'\'';
|
||||
SVal X = CurrSt.GetSValAsScalarOrLoc(CE->getCallee());
|
||||
if (const FunctionDecl* FD = X.getAsFunctionDecl())
|
||||
os << "Call to function '" << FD->getNameAsString() <<'\'';
|
||||
else
|
||||
os << "function call";
|
||||
}
|
||||
|
@ -2675,9 +2675,9 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode<GRState>* N,
|
|||
if (contains(AEffects, MakeCollectable)) {
|
||||
// Get the name of the function.
|
||||
Stmt* S = cast<PostStmt>(N->getLocation()).getStmt();
|
||||
loc::FuncVal FV =
|
||||
cast<loc::FuncVal>(CurrSt.GetSValAsScalarOrLoc(cast<CallExpr>(S)->getCallee()));
|
||||
const std::string& FName = FV.getDecl()->getNameAsString();
|
||||
SVal X = CurrSt.GetSValAsScalarOrLoc(cast<CallExpr>(S)->getCallee());
|
||||
const FunctionDecl* FD = X.getAsFunctionDecl();
|
||||
const std::string& FName = FD->getNameAsString();
|
||||
|
||||
if (TF.isGCEnabled()) {
|
||||
// Determine if the object's reference count was pushed to zero.
|
||||
|
|
|
@ -976,7 +976,7 @@ void GRExprEngine::VisitDeclRefExpr(DeclRefExpr* Ex, NodeTy* Pred, NodeSet& Dst,
|
|||
|
||||
} else if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(D)) {
|
||||
assert(asLValue);
|
||||
SVal V = loc::FuncVal(FD);
|
||||
SVal V = ValMgr.getFunctionPointer(FD);
|
||||
MakeNode(Dst, Ex, Pred, BindExpr(state, Ex, V));
|
||||
return;
|
||||
}
|
||||
|
@ -1369,11 +1369,10 @@ static bool EvalOSAtomic(ExplodedNodeSet<GRState>& Dst,
|
|||
GRStmtNodeBuilder<GRState>& Builder,
|
||||
CallExpr* CE, SVal L,
|
||||
ExplodedNode<GRState>* Pred) {
|
||||
|
||||
if (!isa<loc::FuncVal>(L))
|
||||
const FunctionDecl* FD = L.getAsFunctionDecl();
|
||||
if (!FD)
|
||||
return false;
|
||||
|
||||
const FunctionDecl *FD = cast<loc::FuncVal>(L).getDecl();
|
||||
|
||||
const char *FName = FD->getNameAsCString();
|
||||
|
||||
// Check for compare and swap.
|
||||
|
@ -1473,11 +1472,8 @@ void GRExprEngine::VisitCallRec(CallExpr* CE, NodeTy* Pred,
|
|||
// Check for the "noreturn" attribute.
|
||||
|
||||
SaveAndRestore<bool> OldSink(Builder->BuildSinks);
|
||||
|
||||
if (isa<loc::FuncVal>(L)) {
|
||||
|
||||
FunctionDecl* FD = cast<loc::FuncVal>(L).getDecl();
|
||||
|
||||
const FunctionDecl* FD = L.getAsFunctionDecl();
|
||||
if (FD) {
|
||||
if (FD->getAttr<NoReturnAttr>() || FD->getAttr<AnalyzerNoReturnAttr>())
|
||||
Builder->BuildSinks = true;
|
||||
else {
|
||||
|
@ -1559,10 +1555,9 @@ void GRExprEngine::VisitCallRec(CallExpr* CE, NodeTy* Pred,
|
|||
|
||||
// Evaluate the call.
|
||||
|
||||
if (isa<loc::FuncVal>(L)) {
|
||||
if (FD) {
|
||||
|
||||
if (unsigned id
|
||||
= cast<loc::FuncVal>(L).getDecl()->getBuiltinID(getContext()))
|
||||
if (unsigned id = FD->getBuiltinID(getContext()))
|
||||
switch (id) {
|
||||
case Builtin::BI__builtin_expect: {
|
||||
// For __builtin_expect, just return the value of the subexpression.
|
||||
|
|
|
@ -432,11 +432,11 @@ public:
|
|||
const GRState* state = N->getState();
|
||||
|
||||
SVal X = VMgr.GetSVal(state, CE->getCallee());
|
||||
|
||||
if (!isa<loc::FuncVal>(X))
|
||||
|
||||
const FunctionDecl* FD = X.getAsFunctionDecl();
|
||||
if (!FD)
|
||||
return false;
|
||||
|
||||
FunctionDecl* FD = dyn_cast<FunctionDecl>(cast<loc::FuncVal>(X).getDecl());
|
||||
|
||||
const NonNullAttr* Att = FD->getAttr<NonNullAttr>();
|
||||
|
||||
if (!Att)
|
||||
|
|
|
@ -30,9 +30,25 @@ using llvm::APSInt;
|
|||
// Utility methods.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
const FunctionDecl* SVal::getAsFunctionDecl() const {
|
||||
if (const loc::FuncVal* FV = dyn_cast<loc::FuncVal>(this)) {
|
||||
return FV->getDecl();
|
||||
}
|
||||
|
||||
if (const loc::MemRegionVal* X = dyn_cast<loc::MemRegionVal>(this)) {
|
||||
const MemRegion* R = X->getRegion();
|
||||
if (const CodeTextRegion* CTR = dyn_cast<CodeTextRegion>(R)) {
|
||||
if (CTR->isDeclared())
|
||||
return CTR->getDecl();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// getAsLocSymbol - If this SVal is a location (subclasses Loc) and
|
||||
/// wraps a symbol, return that SymbolRef. Otherwise return a SymbolRef
|
||||
/// where 'isValid()' returns false.
|
||||
/// wraps a symbol, return that SymbolRef. Otherwise return 0.
|
||||
// FIXME: should we consider SymbolRef wrapped in CodeTextRegion?
|
||||
SymbolRef SVal::getAsLocSymbol() const {
|
||||
if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this)) {
|
||||
const MemRegion *R = X->getRegion();
|
||||
|
@ -55,7 +71,8 @@ SymbolRef SVal::getAsLocSymbol() const {
|
|||
}
|
||||
|
||||
/// getAsSymbol - If this Sval wraps a symbol return that SymbolRef.
|
||||
/// Otherwise return a SymbolRef where 'isValid()' returns false.
|
||||
/// Otherwise return 0.
|
||||
// FIXME: should we consider SymbolRef wrapped in CodeTextRegion?
|
||||
SymbolRef SVal::getAsSymbol() const {
|
||||
if (const nonloc::SymbolVal *X = dyn_cast<nonloc::SymbolVal>(this))
|
||||
return X->getSymbol();
|
||||
|
|
Loading…
Reference in New Issue