110e25031STed Kremenek //===- ExprEngineCXX.cpp - ExprEngine support for C++ -----------*- C++ -*-===//
210e25031STed Kremenek //
310e25031STed Kremenek //                     The LLVM Compiler Infrastructure
410e25031STed Kremenek //
510e25031STed Kremenek // This file is distributed under the University of Illinois Open Source
610e25031STed Kremenek // License. See LICENSE.TXT for details.
710e25031STed Kremenek //
810e25031STed Kremenek //===----------------------------------------------------------------------===//
910e25031STed Kremenek //
1010e25031STed Kremenek //  This file defines the C++ expression evaluation engine.
1110e25031STed Kremenek //
1210e25031STed Kremenek //===----------------------------------------------------------------------===//
1310e25031STed Kremenek 
1410e25031STed Kremenek #include "clang/StaticAnalyzer/Core/CheckerManager.h"
1510e25031STed Kremenek #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
1610e25031STed Kremenek #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
17742920c8SJordan Rose #include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
1810e25031STed Kremenek #include "clang/AST/DeclCXX.h"
198fdb59f9STed Kremenek #include "clang/AST/StmtCXX.h"
2010e25031STed Kremenek 
2110e25031STed Kremenek using namespace clang;
2210e25031STed Kremenek using namespace ento;
2310e25031STed Kremenek 
2410e25031STed Kremenek void ExprEngine::CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME,
2510e25031STed Kremenek                                           ExplodedNode *Pred,
2610e25031STed Kremenek                                           ExplodedNodeSet &Dst) {
27e4e5712cSAnna Zaks   StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
282a14c695STed Kremenek   const Expr *tempExpr = ME->GetTemporaryExpr()->IgnoreParens();
2949b1e38eSTed Kremenek   ProgramStateRef state = Pred->getState();
30632e3b7eSTed Kremenek   const LocationContext *LCtx = Pred->getLocationContext();
3110e25031STed Kremenek 
3210e25031STed Kremenek   // Bind the temporary object to the value of the expression. Then bind
3310e25031STed Kremenek   // the expression to the location of the object.
34632e3b7eSTed Kremenek   SVal V = state->getSVal(tempExpr, Pred->getLocationContext());
3510e25031STed Kremenek 
3610e25031STed Kremenek   const MemRegion *R =
37632e3b7eSTed Kremenek     svalBuilder.getRegionManager().getCXXTempObjectRegion(ME, LCtx);
3810e25031STed Kremenek 
3910e25031STed Kremenek   state = state->bindLoc(loc::MemRegionVal(R), V);
40632e3b7eSTed Kremenek   Bldr.generateNode(ME, Pred, state->BindExpr(ME, LCtx, loc::MemRegionVal(R)));
4110e25031STed Kremenek }
4210e25031STed Kremenek 
4311764ab4SBenjamin Kramer void ExprEngine::VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *expr,
4411764ab4SBenjamin Kramer                                              ExplodedNode *Pred,
4511764ab4SBenjamin Kramer                                              ExplodedNodeSet &Dst) {
4611764ab4SBenjamin Kramer   VisitCXXConstructExpr(expr, 0, Pred, Dst);
4711764ab4SBenjamin Kramer }
4811764ab4SBenjamin Kramer 
49f3c12ac3SJordan Rose void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE,
5010e25031STed Kremenek                                        const MemRegion *Dest,
5110e25031STed Kremenek                                        ExplodedNode *Pred,
5210e25031STed Kremenek                                        ExplodedNodeSet &destNodes) {
53f3c12ac3SJordan Rose   CXXConstructorCall Call(CE, Dest, Pred->getState(),
5410e25031STed Kremenek                           Pred->getLocationContext());
5510e25031STed Kremenek 
56f3c12ac3SJordan Rose   ExplodedNodeSet DstPreVisit;
57f3c12ac3SJordan Rose   getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, CE, *this);
58*afe7c2c2SJordan Rose   ExplodedNodeSet DstPreCall;
59*afe7c2c2SJordan Rose   getCheckerManager().runCheckersForPreCall(DstPreCall, DstPreVisit,
60*afe7c2c2SJordan Rose                                             Call, *this);
6110e25031STed Kremenek 
62f3c12ac3SJordan Rose   ExplodedNodeSet DstInvalidated;
63*afe7c2c2SJordan Rose   for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
64f3c12ac3SJordan Rose        I != E; ++I)
65f3c12ac3SJordan Rose     defaultEvalCall(DstInvalidated, *I, Call);
6610e25031STed Kremenek 
67*afe7c2c2SJordan Rose   ExplodedNodeSet DstPostCall;
68*afe7c2c2SJordan Rose   getCheckerManager().runCheckersForPostCall(DstPostCall, DstInvalidated,
69*afe7c2c2SJordan Rose                                              Call, *this);
70*afe7c2c2SJordan Rose   getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, CE, *this);
7110e25031STed Kremenek }
7210e25031STed Kremenek 
7310e25031STed Kremenek void ExprEngine::VisitCXXDestructor(const CXXDestructorDecl *DD,
7410e25031STed Kremenek                                       const MemRegion *Dest,
7510e25031STed Kremenek                                       const Stmt *S,
7610e25031STed Kremenek                                       ExplodedNode *Pred,
7710e25031STed Kremenek                                       ExplodedNodeSet &Dst) {
78e4e5712cSAnna Zaks   StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
7910e25031STed Kremenek   if (!(DD->doesThisDeclarationHaveABody() && AMgr.shouldInlineCall()))
8010e25031STed Kremenek     return;
81142adc49STed Kremenek 
8210e25031STed Kremenek   // Create the context for 'this' region.
83142adc49STed Kremenek   const StackFrameContext *SFC =
8481ce1c8aSTed Kremenek     AnalysisDeclContexts.getContext(DD)->
85142adc49STed Kremenek       getStackFrame(Pred->getLocationContext(), S,
86e594034fSAnna Zaks       currentBuilderContext->getBlock(), currentStmtIdx);
8710e25031STed Kremenek 
8810e25031STed Kremenek   CallEnter PP(S, SFC, Pred->getLocationContext());
8949b1e38eSTed Kremenek   ProgramStateRef state = Pred->getState();
9072b3452cSTed Kremenek   state = state->bindLoc(svalBuilder.getCXXThis(DD->getParent(), SFC),
9172b3452cSTed Kremenek                          loc::MemRegionVal(Dest));
92e594034fSAnna Zaks   Bldr.generateNode(PP, Pred, state);
9310e25031STed Kremenek }
9410e25031STed Kremenek 
9544320367SJordan Rose static bool isPointerToConst(const ParmVarDecl *ParamDecl) {
9644320367SJordan Rose   // FIXME: Copied from ExprEngineCallAndReturn.cpp
9744320367SJordan Rose   QualType PointeeTy = ParamDecl->getOriginalType()->getPointeeType();
9844320367SJordan Rose   if (PointeeTy != QualType() && PointeeTy.isConstQualified() &&
9944320367SJordan Rose       !PointeeTy->isAnyPointerType() && !PointeeTy->isReferenceType()) {
10044320367SJordan Rose     return true;
10144320367SJordan Rose   }
10244320367SJordan Rose   return false;
10344320367SJordan Rose }
10444320367SJordan Rose 
10510e25031STed Kremenek void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
10610e25031STed Kremenek                                    ExplodedNodeSet &Dst) {
107e4e5712cSAnna Zaks   StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
10810e25031STed Kremenek 
109e594034fSAnna Zaks   unsigned blockCount = currentBuilderContext->getCurrentBlockCount();
110d519cae8STed Kremenek   const LocationContext *LCtx = Pred->getLocationContext();
11110e25031STed Kremenek   DefinedOrUnknownSVal symVal =
112d519cae8STed Kremenek     svalBuilder.getConjuredSymbolVal(NULL, CNE, LCtx, CNE->getType(), blockCount);
11310e25031STed Kremenek   const MemRegion *NewReg = cast<loc::MemRegionVal>(symVal).getRegion();
11410e25031STed Kremenek   QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType();
11510e25031STed Kremenek   const ElementRegion *EleReg =
11610e25031STed Kremenek     getStoreManager().GetElementZeroRegion(NewReg, ObjTy);
11744320367SJordan Rose   ProgramStateRef State = Pred->getState();
11810e25031STed Kremenek 
11910e25031STed Kremenek   if (CNE->isArray()) {
12010e25031STed Kremenek     // FIXME: allocating an array requires simulating the constructors.
12110e25031STed Kremenek     // For now, just return a symbolicated region.
12244320367SJordan Rose     State = State->BindExpr(CNE, Pred->getLocationContext(),
123632e3b7eSTed Kremenek                             loc::MemRegionVal(EleReg));
12444320367SJordan Rose     Bldr.generateNode(CNE, Pred, State);
12510e25031STed Kremenek     return;
12610e25031STed Kremenek   }
12710e25031STed Kremenek 
12844320367SJordan Rose   FunctionDecl *FD = CNE->getOperatorNew();
12944320367SJordan Rose   if (FD && FD->isReservedGlobalPlacementOperator()) {
13044320367SJordan Rose     // Non-array placement new should always return the placement location.
13144320367SJordan Rose     SVal PlacementLoc = State->getSVal(CNE->getPlacementArg(0), LCtx);
13244320367SJordan Rose     State = State->BindExpr(CNE, LCtx, PlacementLoc);
13344320367SJordan Rose     // FIXME: Once we have proper support for CXXConstructExprs inside
13444320367SJordan Rose     // CXXNewExpr, we need to make sure that the constructed object is not
13544320367SJordan Rose     // immediately invalidated here. (The placement call should happen before
13644320367SJordan Rose     // the constructor call anyway.)
13744320367SJordan Rose   }
13844320367SJordan Rose 
13944320367SJordan Rose   // Invalidate placement args.
14044320367SJordan Rose 
14144320367SJordan Rose   // FIXME: This is largely copied from invalidateArguments, because
14244320367SJordan Rose   // CallOrObjCMessage is not general enough to handle new-expressions yet.
14344320367SJordan Rose   SmallVector<const MemRegion *, 4> RegionsToInvalidate;
14444320367SJordan Rose 
14544320367SJordan Rose   unsigned Index = 0;
14644320367SJordan Rose   for (CXXNewExpr::const_arg_iterator I = CNE->placement_arg_begin(),
14744320367SJordan Rose                                       E = CNE->placement_arg_end();
14844320367SJordan Rose        I != E; ++I) {
14944320367SJordan Rose     // Pre-increment the argument index to skip over the implicit size arg.
15044320367SJordan Rose     ++Index;
15144320367SJordan Rose     if (FD && Index < FD->getNumParams())
15244320367SJordan Rose       if (isPointerToConst(FD->getParamDecl(Index)))
15344320367SJordan Rose         continue;
15444320367SJordan Rose 
15544320367SJordan Rose     SVal V = State->getSVal(*I, LCtx);
15644320367SJordan Rose 
15744320367SJordan Rose     // If we are passing a location wrapped as an integer, unwrap it and
15844320367SJordan Rose     // invalidate the values referred by the location.
15944320367SJordan Rose     if (nonloc::LocAsInteger *Wrapped = dyn_cast<nonloc::LocAsInteger>(&V))
16044320367SJordan Rose       V = Wrapped->getLoc();
16144320367SJordan Rose     else if (!isa<Loc>(V))
16244320367SJordan Rose       continue;
16344320367SJordan Rose 
16444320367SJordan Rose     if (const MemRegion *R = V.getAsRegion()) {
16544320367SJordan Rose       // Invalidate the value of the variable passed by reference.
16644320367SJordan Rose 
16744320367SJordan Rose       // Are we dealing with an ElementRegion?  If the element type is
16844320367SJordan Rose       // a basic integer type (e.g., char, int) and the underlying region
16944320367SJordan Rose       // is a variable region then strip off the ElementRegion.
17044320367SJordan Rose       // FIXME: We really need to think about this for the general case
17144320367SJordan Rose       //   as sometimes we are reasoning about arrays and other times
17244320367SJordan Rose       //   about (char*), etc., is just a form of passing raw bytes.
17344320367SJordan Rose       //   e.g., void *p = alloca(); foo((char*)p);
17444320367SJordan Rose       if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
17544320367SJordan Rose         // Checking for 'integral type' is probably too promiscuous, but
17644320367SJordan Rose         // we'll leave it in for now until we have a systematic way of
17744320367SJordan Rose         // handling all of these cases.  Eventually we need to come up
17844320367SJordan Rose         // with an interface to StoreManager so that this logic can be
17944320367SJordan Rose         // appropriately delegated to the respective StoreManagers while
18044320367SJordan Rose         // still allowing us to do checker-specific logic (e.g.,
18144320367SJordan Rose         // invalidating reference counts), probably via callbacks.
18244320367SJordan Rose         if (ER->getElementType()->isIntegralOrEnumerationType()) {
18344320367SJordan Rose           const MemRegion *superReg = ER->getSuperRegion();
18444320367SJordan Rose           if (isa<VarRegion>(superReg) || isa<FieldRegion>(superReg) ||
18544320367SJordan Rose               isa<ObjCIvarRegion>(superReg))
18644320367SJordan Rose             R = cast<TypedRegion>(superReg);
18744320367SJordan Rose         }
18844320367SJordan Rose         // FIXME: What about layers of ElementRegions?
18944320367SJordan Rose       }
19044320367SJordan Rose 
19144320367SJordan Rose       // Mark this region for invalidation.  We batch invalidate regions
19244320367SJordan Rose       // below for efficiency.
19344320367SJordan Rose       RegionsToInvalidate.push_back(R);
19444320367SJordan Rose     } else {
19544320367SJordan Rose       // Nuke all other arguments passed by reference.
19644320367SJordan Rose       // FIXME: is this necessary or correct? This handles the non-Region
19744320367SJordan Rose       //  cases.  Is it ever valid to store to these?
19844320367SJordan Rose       State = State->unbindLoc(cast<Loc>(V));
19944320367SJordan Rose     }
20044320367SJordan Rose   }
20144320367SJordan Rose 
20244320367SJordan Rose   // Invalidate designated regions using the batch invalidation API.
20344320367SJordan Rose 
20444320367SJordan Rose   // FIXME: We can have collisions on the conjured symbol if the
20544320367SJordan Rose   //  expression *I also creates conjured symbols.  We probably want
20644320367SJordan Rose   //  to identify conjured symbols by an expression pair: the enclosing
20744320367SJordan Rose   //  expression (the context) and the expression itself.  This should
20844320367SJordan Rose   //  disambiguate conjured symbols.
20944320367SJordan Rose   unsigned Count = currentBuilderContext->getCurrentBlockCount();
21044320367SJordan Rose 
21144320367SJordan Rose   // NOTE: Even if RegionsToInvalidate is empty, we may still invalidate
21244320367SJordan Rose   //  global variables.
21344320367SJordan Rose   State = State->invalidateRegions(RegionsToInvalidate, CNE, Count, LCtx);
21444320367SJordan Rose   Bldr.generateNode(CNE, Pred, State);
21544320367SJordan Rose   return;
21644320367SJordan Rose 
21744320367SJordan Rose   // FIXME: The below code is long-since dead. However, constructor handling
21844320367SJordan Rose   // in new-expressions is far from complete. See PR12014 for more details.
2196047f07eSSebastian Redl #if 0
22010e25031STed Kremenek   // Evaluate constructor arguments.
22110e25031STed Kremenek   const FunctionProtoType *FnType = NULL;
22210e25031STed Kremenek   const CXXConstructorDecl *CD = CNE->getConstructor();
22310e25031STed Kremenek   if (CD)
22410e25031STed Kremenek     FnType = CD->getType()->getAs<FunctionProtoType>();
22510e25031STed Kremenek   ExplodedNodeSet argsEvaluated;
226e594034fSAnna Zaks   Bldr.takeNodes(Pred);
22710e25031STed Kremenek   evalArguments(CNE->constructor_arg_begin(), CNE->constructor_arg_end(),
22810e25031STed Kremenek                 FnType, Pred, argsEvaluated);
229e594034fSAnna Zaks   Bldr.addNodes(argsEvaluated);
23010e25031STed Kremenek 
23110e25031STed Kremenek   // Initialize the object region and bind the 'new' expression.
23210e25031STed Kremenek   for (ExplodedNodeSet::iterator I = argsEvaluated.begin(),
23310e25031STed Kremenek                                  E = argsEvaluated.end(); I != E; ++I) {
23410e25031STed Kremenek 
23549b1e38eSTed Kremenek     ProgramStateRef state = (*I)->getState();
23610e25031STed Kremenek 
23710e25031STed Kremenek     // Accumulate list of regions that are invalidated.
23810e25031STed Kremenek     // FIXME: Eventually we should unify the logic for constructor
23910e25031STed Kremenek     // processing in one place.
24010e25031STed Kremenek     SmallVector<const MemRegion*, 10> regionsToInvalidate;
24110e25031STed Kremenek     for (CXXNewExpr::const_arg_iterator
24210e25031STed Kremenek           ai = CNE->constructor_arg_begin(), ae = CNE->constructor_arg_end();
24310e25031STed Kremenek           ai != ae; ++ai)
24410e25031STed Kremenek     {
245632e3b7eSTed Kremenek       SVal val = state->getSVal(*ai, (*I)->getLocationContext());
24610e25031STed Kremenek       if (const MemRegion *region = val.getAsRegion())
24710e25031STed Kremenek         regionsToInvalidate.push_back(region);
24810e25031STed Kremenek     }
24910e25031STed Kremenek 
25010e25031STed Kremenek     if (ObjTy->isRecordType()) {
25110e25031STed Kremenek       regionsToInvalidate.push_back(EleReg);
25210e25031STed Kremenek       // Invalidate the regions.
2538158ef0dSAnna Zaks       // TODO: Pass the call to new information as the last argument, to limit
2548158ef0dSAnna Zaks       // the globals which will get invalidated.
2551fad6631SJordy Rose       state = state->invalidateRegions(regionsToInvalidate,
2568158ef0dSAnna Zaks                                        CNE, blockCount, 0, 0);
25710e25031STed Kremenek 
25810e25031STed Kremenek     } else {
25910e25031STed Kremenek       // Invalidate the regions.
2608158ef0dSAnna Zaks       // TODO: Pass the call to new information as the last argument, to limit
2618158ef0dSAnna Zaks       // the globals which will get invalidated.
2621fad6631SJordy Rose       state = state->invalidateRegions(regionsToInvalidate,
2638158ef0dSAnna Zaks                                        CNE, blockCount, 0, 0);
26410e25031STed Kremenek 
26510e25031STed Kremenek       if (CNE->hasInitializer()) {
266632e3b7eSTed Kremenek         SVal V = state->getSVal(*CNE->constructor_arg_begin(),
267632e3b7eSTed Kremenek                                 (*I)->getLocationContext());
26810e25031STed Kremenek         state = state->bindLoc(loc::MemRegionVal(EleReg), V);
26910e25031STed Kremenek       } else {
27010e25031STed Kremenek         // Explicitly set to undefined, because currently we retrieve symbolic
27110e25031STed Kremenek         // value from symbolic region.
27210e25031STed Kremenek         state = state->bindLoc(loc::MemRegionVal(EleReg), UndefinedVal());
27310e25031STed Kremenek       }
27410e25031STed Kremenek     }
275632e3b7eSTed Kremenek     state = state->BindExpr(CNE, (*I)->getLocationContext(),
276632e3b7eSTed Kremenek                             loc::MemRegionVal(EleReg));
277e594034fSAnna Zaks     Bldr.generateNode(CNE, *I, state);
27810e25031STed Kremenek   }
2796047f07eSSebastian Redl #endif
28010e25031STed Kremenek }
28110e25031STed Kremenek 
28210e25031STed Kremenek void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE,
28310e25031STed Kremenek                                     ExplodedNode *Pred, ExplodedNodeSet &Dst) {
28464aea652SErik Verbruggen   StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
28564aea652SErik Verbruggen   ProgramStateRef state = Pred->getState();
28664aea652SErik Verbruggen   Bldr.generateNode(CDE, Pred, state);
28710e25031STed Kremenek }
28810e25031STed Kremenek 
2898fdb59f9STed Kremenek void ExprEngine::VisitCXXCatchStmt(const CXXCatchStmt *CS,
2908fdb59f9STed Kremenek                                    ExplodedNode *Pred,
2918fdb59f9STed Kremenek                                    ExplodedNodeSet &Dst) {
2928fdb59f9STed Kremenek   const VarDecl *VD = CS->getExceptionDecl();
293b1279b5cSTed Kremenek   if (!VD) {
294b1279b5cSTed Kremenek     Dst.Add(Pred);
295b1279b5cSTed Kremenek     return;
296b1279b5cSTed Kremenek   }
297b1279b5cSTed Kremenek 
2988fdb59f9STed Kremenek   const LocationContext *LCtx = Pred->getLocationContext();
2998fdb59f9STed Kremenek   SVal V = svalBuilder.getConjuredSymbolVal(CS, LCtx, VD->getType(),
3008fdb59f9STed Kremenek                                  currentBuilderContext->getCurrentBlockCount());
3018fdb59f9STed Kremenek   ProgramStateRef state = Pred->getState();
3028fdb59f9STed Kremenek   state = state->bindLoc(state->getLValue(VD, LCtx), V);
3038fdb59f9STed Kremenek 
3048fdb59f9STed Kremenek   StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
3058fdb59f9STed Kremenek   Bldr.generateNode(CS, Pred, state);
3068fdb59f9STed Kremenek }
3078fdb59f9STed Kremenek 
30810e25031STed Kremenek void ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
30910e25031STed Kremenek                                     ExplodedNodeSet &Dst) {
310e4e5712cSAnna Zaks   StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
311e594034fSAnna Zaks 
31210e25031STed Kremenek   // Get the this object region from StoreManager.
313632e3b7eSTed Kremenek   const LocationContext *LCtx = Pred->getLocationContext();
31410e25031STed Kremenek   const MemRegion *R =
31510e25031STed Kremenek     svalBuilder.getRegionManager().getCXXThisRegion(
31610e25031STed Kremenek                                   getContext().getCanonicalType(TE->getType()),
317632e3b7eSTed Kremenek                                                     LCtx);
31810e25031STed Kremenek 
31949b1e38eSTed Kremenek   ProgramStateRef state = Pred->getState();
32010e25031STed Kremenek   SVal V = state->getSVal(loc::MemRegionVal(R));
321632e3b7eSTed Kremenek   Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V));
32210e25031STed Kremenek }
323