[cfe-commits] r119684 - in /cfe/trunk: include/clang/Checker/PathSensitive/GRExprEngine.h lib/Checker/GRCXXExprEngine.cpp lib/Checker/GRExprEngine.cpp
Marcin Swiderski
marcin.sfider at gmail.com
Wed Nov 17 22:29:23 PST 2010
Author: sfider
Date: Thu Nov 18 00:29:23 2010
New Revision: 119684
URL: http://llvm.org/viewvc/llvm-project?rev=119684&view=rev
Log:
Added method for handling CXXOperatorCallExpr differently from CallExpr if CXXOperatorCallExpr represents method call.
Also fixed returning ExpolodedNodeSet from VisitCXXMethodCallExpr.
Modified:
cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h
cfe/trunk/lib/Checker/GRCXXExprEngine.cpp
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=119684&r1=119683&r2=119684&view=diff
==============================================================================
--- cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h Thu Nov 18 00:29:23 2010
@@ -431,6 +431,9 @@
void VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE, ExplodedNode *Pred,
ExplodedNodeSet &Dst);
+ void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *C,
+ ExplodedNode *Pred, ExplodedNodeSet &Dst);
+
void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
ExplodedNodeSet &Dst);
@@ -454,6 +457,12 @@
ExplodedNode *Pred, ExplodedNodeSet &Dst,
bool FstArgAsLValue = false);
+ /// Evaluate method call itself. Used for CXXMethodCallExpr and
+ /// CXXOperatorCallExpr.
+ void EvalMethodCall(const CallExpr *MCE, const CXXMethodDecl *MD,
+ const Expr *ThisExpr, ExplodedNode *Pred,
+ ExplodedNodeSet &Src, ExplodedNodeSet &Dst);
+
/// EvalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic
/// expressions of the form 'x != 0' and generate new nodes (stored in Dst)
/// with those assumptions.
Modified: cfe/trunk/lib/Checker/GRCXXExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/GRCXXExprEngine.cpp?rev=119684&r1=119683&r2=119684&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/GRCXXExprEngine.cpp (original)
+++ cfe/trunk/lib/Checker/GRCXXExprEngine.cpp Thu Nov 18 00:29:23 2010
@@ -169,13 +169,43 @@
VisitLValue(ObjArgExpr, *I, AllArgsEvaluated);
}
- // Allow checkers to pre-visit the member call.
- ExplodedNodeSet PreVisitChecks;
- CheckerVisit(MCE, PreVisitChecks, AllArgsEvaluated, PreVisitStmtCallback);
-
// Now evaluate the call itself.
const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl());
assert(MD && "not a CXXMethodDecl?");
+ EvalMethodCall(MCE, MD, ObjArgExpr, Pred, AllArgsEvaluated, Dst);
+}
+
+void GRExprEngine::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *C,
+ ExplodedNode *Pred,
+ ExplodedNodeSet &Dst) {
+ const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(C->getCalleeDecl());
+ if (!MD) {
+ // If the operator doesn't represent a method call treat as regural call.
+ VisitCall(C, Pred, C->arg_begin(), C->arg_end(), Dst, false);
+ return;
+ }
+
+ // Determine the type of function we're calling (if available).
+ const FunctionProtoType *Proto = NULL;
+ QualType FnType = C->getCallee()->IgnoreParens()->getType();
+ if (const PointerType *FnTypePtr = FnType->getAs<PointerType>())
+ Proto = FnTypePtr->getPointeeType()->getAs<FunctionProtoType>();
+
+ // Evaluate arguments treating the first one (object method is called on)
+ // as alvalue.
+ ExplodedNodeSet ArgsEvaluated;
+ EvalArguments(C->arg_begin(), C->arg_end(), Proto, Pred, ArgsEvaluated, true);
+
+ // Now evaluate the call itself.
+ EvalMethodCall(C, MD, C->getArg(0), Pred, ArgsEvaluated, Dst);
+}
+
+void GRExprEngine::EvalMethodCall(const CallExpr *MCE, const CXXMethodDecl *MD,
+ const Expr *ThisExpr, ExplodedNode *Pred,
+ ExplodedNodeSet &Src, ExplodedNodeSet &Dst) {
+ // Allow checkers to pre-visit the member call.
+ ExplodedNodeSet PreVisitChecks;
+ CheckerVisit(MCE, PreVisitChecks, Src, PreVisitStmtCallback);
if (!(MD->isThisDeclarationADefinition() && AMgr.shouldInlineCall())) {
// FIXME: conservative method call evaluation.
@@ -183,7 +213,6 @@
return;
}
- ExplodedNodeSet SetupThis;
const StackFrameContext *SFC = AMgr.getStackFrame(MD,
Pred->getLocationContext(),
MCE,
@@ -195,8 +224,8 @@
E = PreVisitChecks.end(); I != E; ++I) {
// Set up 'this' region.
const GRState *state = GetState(*I);
- state = state->bindLoc(loc::MemRegionVal(ThisR),state->getSVal(ObjArgExpr));
- SetupThis.Add(Builder->generateNode(Loc, state, *I));
+ state = state->bindLoc(loc::MemRegionVal(ThisR), state->getSVal(ThisExpr));
+ Dst.Add(Builder->generateNode(Loc, state, *I));
}
}
Modified: cfe/trunk/lib/Checker/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/GRExprEngine.cpp?rev=119684&r1=119683&r2=119684&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Checker/GRExprEngine.cpp Thu Nov 18 00:29:23 2010
@@ -895,8 +895,7 @@
break;
}
- case Stmt::CallExprClass:
- case Stmt::CXXOperatorCallExprClass: {
+ case Stmt::CallExprClass: {
const CallExpr* C = cast<CallExpr>(S);
VisitCall(C, Pred, C->arg_begin(), C->arg_end(), Dst, false);
break;
@@ -916,6 +915,12 @@
break;
}
+ case Stmt::CXXOperatorCallExprClass: {
+ const CXXOperatorCallExpr *C = cast<CXXOperatorCallExpr>(S);
+ VisitCXXOperatorCallExpr(C, Pred, Dst);
+ break;
+ }
+
case Stmt::CXXNewExprClass: {
const CXXNewExpr *NE = cast<CXXNewExpr>(S);
VisitCXXNewExpr(NE, Pred, Dst);
More information about the cfe-commits
mailing list