1 //===- ExprEngineCXX.cpp - ExprEngine support for C++ -----------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the C++ expression evaluation engine.
12 //===----------------------------------------------------------------------===//
14 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
15 #include "clang/AST/DeclCXX.h"
16 #include "clang/AST/StmtCXX.h"
17 #include "clang/Basic/PrettyStackTrace.h"
18 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
19 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
20 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
22 using namespace clang;
25 void ExprEngine::CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME,
27 ExplodedNodeSet &Dst) {
28 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
29 const Expr *tempExpr = ME->GetTemporaryExpr()->IgnoreParens();
30 ProgramStateRef state = Pred->getState();
31 const LocationContext *LCtx = Pred->getLocationContext();
33 state = createTemporaryRegionIfNeeded(state, LCtx, tempExpr, ME);
34 Bldr.generateNode(ME, Pred, state);
37 // FIXME: This is the sort of code that should eventually live in a Core
38 // checker rather than as a special case in ExprEngine.
39 void ExprEngine::performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
40 const CallEvent &Call) {
42 bool AlwaysReturnsLValue;
43 if (const CXXConstructorCall *Ctor = dyn_cast<CXXConstructorCall>(&Call)) {
44 assert(Ctor->getDecl()->isTrivial());
45 assert(Ctor->getDecl()->isCopyOrMoveConstructor());
46 ThisVal = Ctor->getCXXThisVal();
47 AlwaysReturnsLValue = false;
49 assert(cast<CXXMethodDecl>(Call.getDecl())->isTrivial());
50 assert(cast<CXXMethodDecl>(Call.getDecl())->getOverloadedOperator() ==
52 ThisVal = cast<CXXInstanceCall>(Call).getCXXThisVal();
53 AlwaysReturnsLValue = true;
56 const LocationContext *LCtx = Pred->getLocationContext();
61 SVal V = Call.getArgSVal(0);
63 // If the value being copied is not unknown, load from its location to get
64 // an aggregate rvalue.
65 if (Optional<Loc> L = V.getAs<Loc>())
66 V = Pred->getState()->getSVal(*L);
68 assert(V.isUnknown());
70 const Expr *CallExpr = Call.getOriginExpr();
71 evalBind(Dst, CallExpr, Pred, ThisVal, V, true);
73 PostStmt PS(CallExpr, LCtx);
74 for (ExplodedNodeSet::iterator I = Dst.begin(), E = Dst.end();
76 ProgramStateRef State = (*I)->getState();
77 if (AlwaysReturnsLValue)
78 State = State->BindExpr(CallExpr, LCtx, ThisVal);
80 State = bindReturnValue(Call, LCtx, State);
81 Bldr.generateNode(PS, State, *I);
86 /// Returns a region representing the first element of a (possibly
87 /// multi-dimensional) array.
89 /// On return, \p Ty will be set to the base type of the array.
91 /// If the type is not an array type at all, the original value is returned.
92 static SVal makeZeroElementRegion(ProgramStateRef State, SVal LValue,
94 // FIXME: This check is just a temporary workaround, because
95 // ProcessTemporaryDtor sends us NULL regions. It will not be necessary once
96 // we can properly process temporary destructors.
97 if (!LValue.getAsRegion())
100 SValBuilder &SVB = State->getStateManager().getSValBuilder();
101 ASTContext &Ctx = SVB.getContext();
103 while (const ArrayType *AT = Ctx.getAsArrayType(Ty)) {
104 Ty = AT->getElementType();
105 LValue = State->getLValue(Ty, SVB.makeZeroArrayIndex(), LValue);
111 void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE,
113 ExplodedNodeSet &destNodes) {
114 const LocationContext *LCtx = Pred->getLocationContext();
115 ProgramStateRef State = Pred->getState();
117 const MemRegion *Target = 0;
119 // FIXME: Handle arrays, which run the same constructor for every element.
120 // For now, we just run the first constructor (which should still invalidate
121 // the entire array).
123 switch (CE->getConstructionKind()) {
124 case CXXConstructExpr::CK_Complete: {
125 // See if we're constructing an existing region by looking at the next
126 // element in the CFG.
127 const CFGBlock *B = currBldrCtx->getBlock();
128 if (currStmtIdx + 1 < B->size()) {
129 CFGElement Next = (*B)[currStmtIdx+1];
131 // Is this a constructor for a local variable?
132 if (Optional<CFGStmt> StmtElem = Next.getAs<CFGStmt>()) {
133 if (const DeclStmt *DS = dyn_cast<DeclStmt>(StmtElem->getStmt())) {
134 if (const VarDecl *Var = dyn_cast<VarDecl>(DS->getSingleDecl())) {
135 if (Var->getInit()->IgnoreImplicit() == CE) {
136 SVal LValue = State->getLValue(Var, LCtx);
137 QualType Ty = Var->getType();
138 LValue = makeZeroElementRegion(State, LValue, Ty);
139 Target = LValue.getAsRegion();
145 // Is this a constructor for a member?
146 if (Optional<CFGInitializer> InitElem = Next.getAs<CFGInitializer>()) {
147 const CXXCtorInitializer *Init = InitElem->getInitializer();
148 assert(Init->isAnyMemberInitializer());
150 const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
151 Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor,
152 LCtx->getCurrentStackFrame());
153 SVal ThisVal = State->getSVal(ThisPtr);
155 const ValueDecl *Field;
157 if (Init->isIndirectMemberInitializer()) {
158 Field = Init->getIndirectMember();
159 FieldVal = State->getLValue(Init->getIndirectMember(), ThisVal);
161 Field = Init->getMember();
162 FieldVal = State->getLValue(Init->getMember(), ThisVal);
165 QualType Ty = Field->getType();
166 FieldVal = makeZeroElementRegion(State, FieldVal, Ty);
167 Target = FieldVal.getAsRegion();
170 // FIXME: This will eventually need to handle new-expressions as well.
171 // Don't forget to update the pre-constructor initialization code below.
174 // If we couldn't find an existing region to construct into, assume we're
175 // constructing a temporary.
177 MemRegionManager &MRMgr = getSValBuilder().getRegionManager();
178 Target = MRMgr.getCXXTempObjectRegion(CE, LCtx);
183 case CXXConstructExpr::CK_VirtualBase:
184 // Make sure we are not calling virtual base class initializers twice.
185 // Only the most-derived object should initialize virtual base classes.
186 if (const Stmt *Outer = LCtx->getCurrentStackFrame()->getCallSite()) {
187 const CXXConstructExpr *OuterCtor = dyn_cast<CXXConstructExpr>(Outer);
189 switch (OuterCtor->getConstructionKind()) {
190 case CXXConstructExpr::CK_NonVirtualBase:
191 case CXXConstructExpr::CK_VirtualBase:
195 case CXXConstructExpr::CK_Complete:
196 case CXXConstructExpr::CK_Delegating:
202 case CXXConstructExpr::CK_NonVirtualBase:
203 case CXXConstructExpr::CK_Delegating: {
204 const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
205 Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor,
206 LCtx->getCurrentStackFrame());
207 SVal ThisVal = State->getSVal(ThisPtr);
209 if (CE->getConstructionKind() == CXXConstructExpr::CK_Delegating) {
210 Target = ThisVal.getAsRegion();
212 // Cast to the base type.
214 (CE->getConstructionKind() == CXXConstructExpr::CK_VirtualBase);
215 SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, CE->getType(),
217 Target = BaseVal.getAsRegion();
223 CallEventManager &CEMgr = getStateManager().getCallEventManager();
224 CallEventRef<CXXConstructorCall> Call =
225 CEMgr.getCXXConstructorCall(CE, Target, State, LCtx);
227 ExplodedNodeSet DstPreVisit;
228 getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, CE, *this);
230 ExplodedNodeSet PreInitialized;
232 StmtNodeBuilder Bldr(DstPreVisit, PreInitialized, *currBldrCtx);
233 if (CE->requiresZeroInitialization()) {
234 // Type of the zero doesn't matter.
235 SVal ZeroVal = svalBuilder.makeZeroVal(getContext().CharTy);
237 for (ExplodedNodeSet::iterator I = DstPreVisit.begin(),
238 E = DstPreVisit.end();
240 ProgramStateRef State = (*I)->getState();
241 // FIXME: Once we properly handle constructors in new-expressions, we'll
242 // need to invalidate the region before setting a default value, to make
243 // sure there aren't any lingering bindings around. This probably needs
244 // to happen regardless of whether or not the object is zero-initialized
245 // to handle random fields of a placement-initialized object picking up
246 // old bindings. We might only want to do it when we need to, though.
247 // FIXME: This isn't actually correct for arrays -- we need to zero-
248 // initialize the entire array, not just the first element -- but our
249 // handling of arrays everywhere else is weak as well, so this shouldn't
250 // actually make things worse. Placement new makes this tricky as well,
251 // since it's then possible to be initializing one part of a multi-
252 // dimensional array.
253 State = State->bindDefault(loc::MemRegionVal(Target), ZeroVal);
254 Bldr.generateNode(CE, *I, State, /*tag=*/0, ProgramPoint::PreStmtKind);
259 ExplodedNodeSet DstPreCall;
260 getCheckerManager().runCheckersForPreCall(DstPreCall, PreInitialized,
263 ExplodedNodeSet DstEvaluated;
264 StmtNodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx);
266 bool IsArray = isa<ElementRegion>(Target);
267 if (CE->getConstructor()->isTrivial() &&
268 CE->getConstructor()->isCopyOrMoveConstructor() &&
270 // FIXME: Handle other kinds of trivial constructors as well.
271 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
273 performTrivialCopy(Bldr, *I, *Call);
276 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
278 defaultEvalCall(Bldr, *I, *Call);
281 ExplodedNodeSet DstPostCall;
282 getCheckerManager().runCheckersForPostCall(DstPostCall, DstEvaluated,
284 getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, CE, *this);
287 void ExprEngine::VisitCXXDestructor(QualType ObjectType,
288 const MemRegion *Dest,
292 ExplodedNodeSet &Dst) {
293 const LocationContext *LCtx = Pred->getLocationContext();
294 ProgramStateRef State = Pred->getState();
296 // FIXME: We need to run the same destructor on every element of the array.
297 // This workaround will just run the first destructor (which will still
298 // invalidate the entire array).
299 SVal DestVal = UnknownVal();
301 DestVal = loc::MemRegionVal(Dest);
302 DestVal = makeZeroElementRegion(State, DestVal, ObjectType);
303 Dest = DestVal.getAsRegion();
305 const CXXRecordDecl *RecordDecl = ObjectType->getAsCXXRecordDecl();
306 assert(RecordDecl && "Only CXXRecordDecls should have destructors");
307 const CXXDestructorDecl *DtorDecl = RecordDecl->getDestructor();
309 CallEventManager &CEMgr = getStateManager().getCallEventManager();
310 CallEventRef<CXXDestructorCall> Call =
311 CEMgr.getCXXDestructorCall(DtorDecl, S, Dest, IsBaseDtor, State, LCtx);
313 PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
314 Call->getSourceRange().getBegin(),
315 "Error evaluating destructor");
317 ExplodedNodeSet DstPreCall;
318 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred,
321 ExplodedNodeSet DstInvalidated;
322 StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);
323 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
325 defaultEvalCall(Bldr, *I, *Call);
327 ExplodedNodeSet DstPostCall;
328 getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated,
332 void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
333 ExplodedNodeSet &Dst) {
334 // FIXME: Much of this should eventually migrate to CXXAllocatorCall.
335 // Also, we need to decide how allocators actually work -- they're not
336 // really part of the CXXNewExpr because they happen BEFORE the
337 // CXXConstructExpr subexpression. See PR12014 for some discussion.
339 unsigned blockCount = currBldrCtx->blockCount();
340 const LocationContext *LCtx = Pred->getLocationContext();
341 DefinedOrUnknownSVal symVal = UnknownVal();
342 FunctionDecl *FD = CNE->getOperatorNew();
344 bool IsStandardGlobalOpNewFunction = false;
345 if (FD && !isa<CXXMethodDecl>(FD) && !FD->isVariadic()) {
346 if (FD->getNumParams() == 2) {
347 QualType T = FD->getParamDecl(1)->getType();
348 if (const IdentifierInfo *II = T.getBaseTypeIdentifier())
349 // NoThrow placement new behaves as a standard new.
350 IsStandardGlobalOpNewFunction = II->getName().equals("nothrow_t");
353 // Placement forms are considered non-standard.
354 IsStandardGlobalOpNewFunction = (FD->getNumParams() == 1);
357 // We assume all standard global 'operator new' functions allocate memory in
358 // heap. We realize this is an approximation that might not correctly model
359 // a custom global allocator.
360 if (IsStandardGlobalOpNewFunction)
361 symVal = svalBuilder.getConjuredHeapSymbolVal(CNE, LCtx, blockCount);
363 symVal = svalBuilder.conjureSymbolVal(0, CNE, LCtx, CNE->getType(),
366 ProgramStateRef State = Pred->getState();
367 CallEventManager &CEMgr = getStateManager().getCallEventManager();
368 CallEventRef<CXXAllocatorCall> Call =
369 CEMgr.getCXXAllocatorCall(CNE, State, LCtx);
371 // Invalidate placement args.
372 // FIXME: Once we figure out how we want allocators to work,
373 // we should be using the usual pre-/(default-)eval-/post-call checks here.
374 State = Call->invalidateRegions(blockCount);
378 // If this allocation function is not declared as non-throwing, failures
379 // /must/ be signalled by exceptions, and thus the return value will never be
380 // NULL. -fno-exceptions does not influence this semantics.
381 // FIXME: GCC has a -fcheck-new option, which forces it to consider the case
382 // where new can return NULL. If we end up supporting that option, we can
383 // consider adding a check for it here.
384 // C++11 [basic.stc.dynamic.allocation]p3.
386 QualType Ty = FD->getType();
387 if (const FunctionProtoType *ProtoType = Ty->getAs<FunctionProtoType>())
388 if (!ProtoType->isNothrow(getContext()))
389 State = State->assume(symVal, true);
392 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
394 if (CNE->isArray()) {
395 // FIXME: allocating an array requires simulating the constructors.
396 // For now, just return a symbolicated region.
397 const MemRegion *NewReg = symVal.castAs<loc::MemRegionVal>().getRegion();
398 QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType();
399 const ElementRegion *EleReg =
400 getStoreManager().GetElementZeroRegion(NewReg, ObjTy);
401 State = State->BindExpr(CNE, Pred->getLocationContext(),
402 loc::MemRegionVal(EleReg));
403 Bldr.generateNode(CNE, Pred, State);
407 // FIXME: Once we have proper support for CXXConstructExprs inside
408 // CXXNewExpr, we need to make sure that the constructed object is not
409 // immediately invalidated here. (The placement call should happen before
410 // the constructor call anyway.)
411 SVal Result = symVal;
412 if (FD && FD->isReservedGlobalPlacementOperator()) {
413 // Non-array placement new should always return the placement location.
414 SVal PlacementLoc = State->getSVal(CNE->getPlacementArg(0), LCtx);
415 Result = svalBuilder.evalCast(PlacementLoc, CNE->getType(),
416 CNE->getPlacementArg(0)->getType());
419 // Bind the address of the object, then check to see if we cached out.
420 State = State->BindExpr(CNE, LCtx, Result);
421 ExplodedNode *NewN = Bldr.generateNode(CNE, Pred, State);
425 // If the type is not a record, we won't have a CXXConstructExpr as an
426 // initializer. Copy the value over.
427 if (const Expr *Init = CNE->getInitializer()) {
428 if (!isa<CXXConstructExpr>(Init)) {
429 assert(Bldr.getResults().size() == 1);
430 Bldr.takeNodes(NewN);
431 evalBind(Dst, CNE, NewN, Result, State->getSVal(Init, LCtx),
432 /*FirstInit=*/IsStandardGlobalOpNewFunction);
437 void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE,
438 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
439 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
440 ProgramStateRef state = Pred->getState();
441 Bldr.generateNode(CDE, Pred, state);
444 void ExprEngine::VisitCXXCatchStmt(const CXXCatchStmt *CS,
446 ExplodedNodeSet &Dst) {
447 const VarDecl *VD = CS->getExceptionDecl();
453 const LocationContext *LCtx = Pred->getLocationContext();
454 SVal V = svalBuilder.conjureSymbolVal(CS, LCtx, VD->getType(),
455 currBldrCtx->blockCount());
456 ProgramStateRef state = Pred->getState();
457 state = state->bindLoc(state->getLValue(VD, LCtx), V);
459 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
460 Bldr.generateNode(CS, Pred, state);
463 void ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
464 ExplodedNodeSet &Dst) {
465 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
467 // Get the this object region from StoreManager.
468 const LocationContext *LCtx = Pred->getLocationContext();
470 svalBuilder.getRegionManager().getCXXThisRegion(
471 getContext().getCanonicalType(TE->getType()),
474 ProgramStateRef state = Pred->getState();
475 SVal V = state->getSVal(loc::MemRegionVal(R));
476 Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V));