[cfe-commits] r100098 - in /cfe/trunk: include/clang/Checker/PathSensitive/GRExprEngine.h lib/Checker/GRExprEngine.cpp
Zhongxing Xu
xuzhongxing at gmail.com
Thu Apr 1 00:58:50 PDT 2010
Author: zhongxingxu
Date: Thu Apr 1 02:58:50 2010
New Revision: 100098
URL: http://llvm.org/viewvc/llvm-project?rev=100098&view=rev
Log:
Initial support for visiting CXXMemberCallExpr.
Modified:
cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h
cfe/trunk/lib/Checker/GRExprEngine.cpp
Modified: cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h?rev=100098&r1=100097&r2=100098&view=diff
==============================================================================
--- cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h Thu Apr 1 02:58:50 2010
@@ -348,6 +348,10 @@
void VisitCXXConstructExpr(const CXXConstructExpr *E, SVal Dest,
ExplodedNode *Pred,
ExplodedNodeSet &Dst);
+
+ void VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE, ExplodedNode *Pred,
+ ExplodedNodeSet &Dst);
+
void VisitAggExpr(const Expr *E, SVal Dest, ExplodedNode *Pred,
ExplodedNodeSet &Dst);
@@ -356,7 +360,7 @@
ExplodedNodeSet &Dst);
/// Synthesize CXXThisRegion.
- const CXXThisRegion *getCXXThisRegion(const CXXConstructExpr *E,
+ const CXXThisRegion *getCXXThisRegion(const CXXMethodDecl *MD,
const StackFrameContext *SFC);
/// EvalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic
Modified: cfe/trunk/lib/Checker/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/GRExprEngine.cpp?rev=100098&r1=100097&r2=100098&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Checker/GRExprEngine.cpp Thu Apr 1 02:58:50 2010
@@ -584,7 +584,6 @@
switch (S->getStmtClass()) {
// C++ stuff we don't support yet.
- case Stmt::CXXMemberCallExprClass:
case Stmt::CXXNamedCastExprClass:
case Stmt::CXXStaticCastExprClass:
case Stmt::CXXDynamicCastExprClass:
@@ -673,6 +672,12 @@
break;
}
+ case Stmt::CXXMemberCallExprClass: {
+ CXXMemberCallExpr *MCE = cast<CXXMemberCallExpr>(S);
+ VisitCXXMemberCallExpr(MCE, Pred, Dst);
+ break;
+ }
+
// FIXME: ChooseExpr is really a constant. We need to fix
// the CFG do not model them as explicit control-flow.
@@ -1342,7 +1347,7 @@
// Bind the constructed object value to CXXConstructExpr.
if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(CE)) {
- const CXXThisRegion *ThisR = getCXXThisRegion(CCE, LocCtx);
+ const CXXThisRegion *ThisR = getCXXThisRegion(CCE->getConstructor(),LocCtx);
// We might not have 'this' region in the binding if we didn't inline
// the ctor call.
SVal ThisV = state->getSVal(ThisR);
@@ -3222,7 +3227,7 @@
Pred->getLocationContext(),
E, Builder->getBlock(), Builder->getIndex());
- const CXXThisRegion *ThisR = getCXXThisRegion(E, SFC);
+ const CXXThisRegion *ThisR = getCXXThisRegion(E->getConstructor(), SFC);
CallEnter Loc(E, CD, Pred->getLocationContext());
for (ExplodedNodeSet::iterator NI = ArgsEvaluated.begin(),
@@ -3236,12 +3241,90 @@
}
}
-const CXXThisRegion *GRExprEngine::getCXXThisRegion(const CXXConstructExpr *E,
+void GRExprEngine::VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE,
+ ExplodedNode *Pred,
+ ExplodedNodeSet &Dst) {
+ // Get the method type.
+ const FunctionProtoType *FnType =
+ MCE->getCallee()->getType()->getAs<FunctionProtoType>();
+ assert(FnType && "Method type not available");
+
+ // Evaluate explicit arguments with a worklist.
+ CallExpr::arg_iterator AB = const_cast<CXXMemberCallExpr*>(MCE)->arg_begin(),
+ AE = const_cast<CXXMemberCallExpr*>(MCE)->arg_end();
+ llvm::SmallVector<CallExprWLItem, 20> WorkList;
+ WorkList.reserve(AE - AB);
+ WorkList.push_back(CallExprWLItem(AB, Pred));
+ ExplodedNodeSet ArgsEvaluated;
+
+ while (!WorkList.empty()) {
+ CallExprWLItem Item = WorkList.back();
+ WorkList.pop_back();
+
+ if (Item.I == AE) {
+ ArgsEvaluated.insert(Item.N);
+ continue;
+ }
+
+ ExplodedNodeSet Tmp;
+ const unsigned ParamIdx = Item.I - AB;
+ bool VisitAsLvalue = FnType->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));
+ }
+ // Evaluate the implicit object argument.
+ ExplodedNodeSet AllArgsEvaluated;
+ const MemberExpr *ME = dyn_cast<MemberExpr>(MCE->getCallee()->IgnoreParens());
+ if (!ME)
+ return;
+ Expr *ObjArgExpr = ME->getBase();
+ for (ExplodedNodeSet::iterator I = ArgsEvaluated.begin(),
+ E = ArgsEvaluated.end(); I != E; ++I) {
+ if (ME->isArrow())
+ Visit(ObjArgExpr, *I, AllArgsEvaluated);
+ else
+ VisitLValue(ObjArgExpr, *I, AllArgsEvaluated);
+ }
+
+ const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl());
+ assert(MD && "not a CXXMethodDecl?");
+
+ if (!MD->isThisDeclarationADefinition())
+ // FIXME: conservative method call evaluation.
+ return;
+
+ const StackFrameContext *SFC = AMgr.getStackFrame(MD,
+ Pred->getLocationContext(),
+ MCE,
+ Builder->getBlock(),
+ Builder->getIndex());
+ const CXXThisRegion *ThisR = getCXXThisRegion(MD, SFC);
+ CallEnter Loc(MCE, MD, Pred->getLocationContext());
+ for (ExplodedNodeSet::iterator I = AllArgsEvaluated.begin(),
+ E = AllArgsEvaluated.end(); I != E; ++I) {
+ // Set up 'this' region.
+ const GRState *state = GetState(*I);
+ state = state->bindLoc(loc::MemRegionVal(ThisR),state->getSVal(ObjArgExpr));
+ ExplodedNode *N = Builder->generateNode(Loc, state, *I);
+ if (N)
+ Dst.Add(N);
+ }
+}
+
+const CXXThisRegion *GRExprEngine::getCXXThisRegion(const CXXMethodDecl *D,
const StackFrameContext *SFC) {
- Type *T = E->getConstructor()->getParent()->getTypeForDecl();
+ Type *T = D->getParent()->getTypeForDecl();
QualType PT = getContext().getPointerType(QualType(T,0));
return ValMgr.getRegionManager().getCXXThisRegion(PT, SFC);
}
+
//===----------------------------------------------------------------------===//
// Checker registration/lookup.
//===----------------------------------------------------------------------===//
More information about the cfe-commits
mailing list