#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"
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);
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);
}
}
+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.
//===----------------------------------------------------------------------===//
#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"
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();
+ Store store = state->getStore();
- CallExpr::const_arg_iterator AI = CE->arg_begin(), AE = CE->arg_end();
+ 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.
- Store store = state->getStore();
- for (; AI != AE; ++AI, ++PI) {
- SVal ArgVal = state->getSVal(*AI);
- store = Bind(store, ValMgr.makeLoc(MRMgr.getVarRegion(*PI, frame)), ArgVal);
- }
+ // 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);
}