forked from OSchip/llvm-project
Add VisitCXXContructExpr logic to the analyzer. This still has not fully worked
since RemoveDeadBinding mistakenly remove the binding to CXXThisRegion. llvm-svn: 98629
This commit is contained in:
parent
421dd12853
commit
0eb690390d
|
@ -347,7 +347,10 @@ protected:
|
|||
|
||||
void VisitCXXThisExpr(CXXThisExpr *TE, ExplodedNode *Pred,
|
||||
ExplodedNodeSet & Dst);
|
||||
|
||||
|
||||
void VisitCXXConstructExpr(const CXXConstructExpr *E, SVal Dest,
|
||||
ExplodedNode *Pred,
|
||||
ExplodedNodeSet &Dst);
|
||||
/// Create a C++ temporary object for an rvalue.
|
||||
void CreateCXXTemporaryObject(Expr *Ex, ExplodedNode *Pred,
|
||||
ExplodedNodeSet &Dst);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "clang/AST/CharUnits.h"
|
||||
#include "clang/AST/ParentMap.h"
|
||||
#include "clang/AST/StmtObjC.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/Basic/Builtins.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
|
@ -2335,7 +2336,11 @@ void GRExprEngine::VisitDeclStmt(DeclStmt *DS, ExplodedNode *Pred,
|
|||
ExplodedNodeSet Tmp;
|
||||
|
||||
if (InitEx) {
|
||||
if (VD->getType()->isReferenceType())
|
||||
if (const CXXConstructExpr *E = dyn_cast<CXXConstructExpr>(InitEx)) {
|
||||
VisitCXXConstructExpr(E, GetState(Pred)->getLValue(VD,
|
||||
Pred->getLocationContext()), Pred, Dst);
|
||||
return;
|
||||
} else if (VD->getType()->isReferenceType())
|
||||
VisitLValue(InitEx, Pred, Tmp);
|
||||
else
|
||||
Visit(InitEx, Pred, Tmp);
|
||||
|
@ -2826,7 +2831,8 @@ void GRExprEngine::VisitCXXThisExpr(CXXThisExpr *TE, ExplodedNode *Pred,
|
|||
ExplodedNodeSet & Dst) {
|
||||
// Get the this object region from StoreManager.
|
||||
const MemRegion *R =
|
||||
ValMgr.getRegionManager().getCXXThisRegion(TE->getType(),
|
||||
ValMgr.getRegionManager().getCXXThisRegion(
|
||||
getContext().getCanonicalType(TE->getType()),
|
||||
Pred->getLocationContext());
|
||||
|
||||
const GRState *state = GetState(Pred);
|
||||
|
@ -3126,6 +3132,78 @@ void GRExprEngine::CreateCXXTemporaryObject(Expr *Ex, ExplodedNode *Pred,
|
|||
}
|
||||
}
|
||||
|
||||
void GRExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E, SVal Dest,
|
||||
ExplodedNode *Pred,
|
||||
ExplodedNodeSet &Dst) {
|
||||
|
||||
const CXXConstructorDecl *CD = E->getConstructor();
|
||||
assert(CD);
|
||||
|
||||
if (!CD->isThisDeclarationADefinition())
|
||||
// FIXME: invalidate the object.
|
||||
return;
|
||||
|
||||
|
||||
// Evaluate other arguments.
|
||||
CXXConstructExpr::arg_iterator AB
|
||||
= const_cast<CXXConstructExpr*>(E)->arg_begin();
|
||||
CXXConstructExpr::arg_iterator AE
|
||||
= const_cast<CXXConstructExpr*>(E)->arg_end();
|
||||
llvm::SmallVector<CallExprWLItem, 20> WorkList;
|
||||
WorkList.reserve(AE - AB);
|
||||
WorkList.push_back(CallExprWLItem(AB, Pred));
|
||||
ExplodedNodeSet ArgsEvaluated;
|
||||
const FunctionProtoType *Proto = CD->getType()->getAs<FunctionProtoType>();
|
||||
|
||||
while (!WorkList.empty()) {
|
||||
CallExprWLItem Item = WorkList.back();
|
||||
WorkList.pop_back();
|
||||
|
||||
if (Item.I == AE) {
|
||||
ArgsEvaluated.insert(Item.N);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Evaluate the argument.
|
||||
ExplodedNodeSet Tmp;
|
||||
const unsigned ParamIdx = Item.I - AB;
|
||||
|
||||
bool VisitAsLvalue = false;
|
||||
|
||||
if (ParamIdx < Proto->getNumArgs())
|
||||
VisitAsLvalue = Proto->getArgType(ParamIdx)->isReferenceType();
|
||||
|
||||
if (VisitAsLvalue)
|
||||
VisitLValue(*Item.I, Item.N, Tmp);
|
||||
else
|
||||
Visit(*Item.I, Item.N, Tmp);
|
||||
|
||||
++(Item.I);
|
||||
|
||||
for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI)
|
||||
WorkList.push_back(CallExprWLItem(Item.I, *NI));
|
||||
}
|
||||
// The callee stack frame context used to create the 'this' parameter region.
|
||||
const StackFrameContext *SFC = AMgr.getStackFrame(CD,
|
||||
Pred->getLocationContext(),
|
||||
E, Builder->getBlock(), Builder->getIndex());
|
||||
|
||||
Type *T = CD->getParent()->getTypeForDecl();
|
||||
QualType PT = getContext().getPointerType(QualType(T,0));
|
||||
const CXXThisRegion *ThisR = ValMgr.getRegionManager().getCXXThisRegion(PT,
|
||||
SFC);
|
||||
|
||||
CallEnter Loc(E, CD, Pred->getLocationContext());
|
||||
for (ExplodedNodeSet::iterator NI = ArgsEvaluated.begin(),
|
||||
NE = ArgsEvaluated.end(); NI != NE; ++NI) {
|
||||
const GRState *state = GetState(*NI);
|
||||
// Setup 'this' region.
|
||||
state = state->bindLoc(loc::MemRegionVal(ThisR), Dest);
|
||||
ExplodedNode *N = Builder->generateNode(Loc, state, Pred);
|
||||
if (N)
|
||||
Dst.Add(N);
|
||||
}
|
||||
}
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Checker registration/lookup.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include "clang/Analysis/Support/Optional.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "clang/AST/CharUnits.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/ExprCXX.h"
|
||||
|
||||
#include "llvm/ADT/ImmutableMap.h"
|
||||
#include "llvm/ADT/ImmutableList.h"
|
||||
|
@ -1841,18 +1843,29 @@ Store RegionStoreManager::RemoveDeadBindings(Store store, Stmt* Loc,
|
|||
GRState const *RegionStoreManager::EnterStackFrame(GRState const *state,
|
||||
StackFrameContext const *frame) {
|
||||
FunctionDecl const *FD = cast<FunctionDecl>(frame->getDecl());
|
||||
CallExpr const *CE = cast<CallExpr>(frame->getCallSite());
|
||||
|
||||
FunctionDecl::param_const_iterator PI = FD->param_begin();
|
||||
|
||||
CallExpr::const_arg_iterator AI = CE->arg_begin(), AE = CE->arg_end();
|
||||
|
||||
// Copy the arg expression value to the arg variables.
|
||||
Store store = state->getStore();
|
||||
for (; AI != AE; ++AI, ++PI) {
|
||||
SVal ArgVal = state->getSVal(*AI);
|
||||
store = Bind(store, ValMgr.makeLoc(MRMgr.getVarRegion(*PI, frame)), ArgVal);
|
||||
}
|
||||
|
||||
if (CallExpr const *CE = dyn_cast<CallExpr>(frame->getCallSite())) {
|
||||
CallExpr::const_arg_iterator AI = CE->arg_begin(), AE = CE->arg_end();
|
||||
|
||||
// Copy the arg expression value to the arg variables.
|
||||
for (; AI != AE; ++AI, ++PI) {
|
||||
SVal ArgVal = state->getSVal(*AI);
|
||||
store = Bind(store, ValMgr.makeLoc(MRMgr.getVarRegion(*PI,frame)),ArgVal);
|
||||
}
|
||||
} else if (const CXXConstructExpr *CE =
|
||||
dyn_cast<CXXConstructExpr>(frame->getCallSite())) {
|
||||
CXXConstructExpr::const_arg_iterator AI = CE->arg_begin(),
|
||||
AE = CE->arg_end();
|
||||
|
||||
// Copy the arg expression value to the arg variables.
|
||||
for (; AI != AE; ++AI, ++PI) {
|
||||
SVal ArgVal = state->getSVal(*AI);
|
||||
store = Bind(store, ValMgr.makeLoc(MRMgr.getVarRegion(*PI,frame)),ArgVal);
|
||||
}
|
||||
} else
|
||||
assert(0 && "Unhandled call expression.");
|
||||
|
||||
return state->makeWithStore(store);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue