ExprEngineCXX.cpp revision 6bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89
1//===- ExprEngineCXX.cpp - ExprEngine support for C++ -----------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file defines the C++ expression evaluation engine.
11//
12//===----------------------------------------------------------------------===//
13
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"
21
22using namespace clang;
23using namespace ento;
24
25void ExprEngine::CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME,
26                                          ExplodedNode *Pred,
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();
32
33  state = createTemporaryRegionIfNeeded(state, LCtx, tempExpr, ME);
34  Bldr.generateNode(ME, Pred, state);
35}
36
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.
39void ExprEngine::performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
40                                    const CallEvent &Call) {
41  SVal ThisVal;
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;
48  } else {
49    assert(cast<CXXMethodDecl>(Call.getDecl())->isTrivial());
50    assert(cast<CXXMethodDecl>(Call.getDecl())->getOverloadedOperator() ==
51           OO_Equal);
52    ThisVal = cast<CXXInstanceCall>(Call).getCXXThisVal();
53    AlwaysReturnsLValue = true;
54  }
55
56  const LocationContext *LCtx = Pred->getLocationContext();
57
58  ExplodedNodeSet Dst;
59  Bldr.takeNodes(Pred);
60
61  SVal V = Call.getArgSVal(0);
62
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);
67  else
68    assert(V.isUnknown());
69
70  const Expr *CallExpr = Call.getOriginExpr();
71  evalBind(Dst, CallExpr, Pred, ThisVal, V, true);
72
73  PostStmt PS(CallExpr, LCtx);
74  for (ExplodedNodeSet::iterator I = Dst.begin(), E = Dst.end();
75       I != E; ++I) {
76    ProgramStateRef State = (*I)->getState();
77    if (AlwaysReturnsLValue)
78      State = State->BindExpr(CallExpr, LCtx, ThisVal);
79    else
80      State = bindReturnValue(Call, LCtx, State);
81    Bldr.generateNode(PS, State, *I);
82  }
83}
84
85
86/// Returns a region representing the first element of a (possibly
87/// multi-dimensional) array.
88///
89/// On return, \p Ty will be set to the base type of the array.
90///
91/// If the type is not an array type at all, the original value is returned.
92static SVal makeZeroElementRegion(ProgramStateRef State, SVal LValue,
93                                  QualType &Ty) {
94  SValBuilder &SVB = State->getStateManager().getSValBuilder();
95  ASTContext &Ctx = SVB.getContext();
96
97  while (const ArrayType *AT = Ctx.getAsArrayType(Ty)) {
98    Ty = AT->getElementType();
99    LValue = State->getLValue(Ty, SVB.makeZeroArrayIndex(), LValue);
100  }
101
102  return LValue;
103}
104
105
106static const MemRegion *getRegionForConstructedObject(
107    const CXXConstructExpr *CE, ExplodedNode *Pred, ExprEngine &Eng,
108    unsigned int CurrStmtIdx) {
109  const LocationContext *LCtx = Pred->getLocationContext();
110  ProgramStateRef State = Pred->getState();
111  const NodeBuilderContext &CurrBldrCtx = Eng.getBuilderContext();
112
113  // See if we're constructing an existing region by looking at the next
114  // element in the CFG.
115  const CFGBlock *B = CurrBldrCtx.getBlock();
116  unsigned int NextStmtIdx = CurrStmtIdx + 1;
117  if (NextStmtIdx < B->size()) {
118    CFGElement Next = (*B)[NextStmtIdx];
119
120    // Is this a destructor? If so, we might be in the middle of an assignment
121    // to a local or member: look ahead one more element to see what we find.
122    while (Next.getAs<CFGImplicitDtor>() && NextStmtIdx + 1 < B->size()) {
123      ++NextStmtIdx;
124      Next = (*B)[NextStmtIdx];
125    }
126
127    // Is this a constructor for a local variable?
128    if (Optional<CFGStmt> StmtElem = Next.getAs<CFGStmt>()) {
129      if (const DeclStmt *DS = dyn_cast<DeclStmt>(StmtElem->getStmt())) {
130        if (const VarDecl *Var = dyn_cast<VarDecl>(DS->getSingleDecl())) {
131          if (Var->getInit() && Var->getInit()->IgnoreImplicit() == CE) {
132            SVal LValue = State->getLValue(Var, LCtx);
133            QualType Ty = Var->getType();
134            LValue = makeZeroElementRegion(State, LValue, Ty);
135            return LValue.getAsRegion();
136          }
137        }
138      }
139    }
140
141    // Is this a constructor for a member?
142    if (Optional<CFGInitializer> InitElem = Next.getAs<CFGInitializer>()) {
143      const CXXCtorInitializer *Init = InitElem->getInitializer();
144      assert(Init->isAnyMemberInitializer());
145
146      const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
147      Loc ThisPtr = Eng.getSValBuilder().getCXXThis(CurCtor,
148          LCtx->getCurrentStackFrame());
149      SVal ThisVal = State->getSVal(ThisPtr);
150
151      const ValueDecl *Field;
152      SVal FieldVal;
153      if (Init->isIndirectMemberInitializer()) {
154        Field = Init->getIndirectMember();
155        FieldVal = State->getLValue(Init->getIndirectMember(), ThisVal);
156      } else {
157        Field = Init->getMember();
158        FieldVal = State->getLValue(Init->getMember(), ThisVal);
159      }
160
161      QualType Ty = Field->getType();
162      FieldVal = makeZeroElementRegion(State, FieldVal, Ty);
163      return FieldVal.getAsRegion();
164    }
165
166    // FIXME: This will eventually need to handle new-expressions as well.
167    // Don't forget to update the pre-constructor initialization code in
168    // ExprEngine::VisitCXXConstructExpr.
169  }
170
171  // If we couldn't find an existing region to construct into, assume we're
172  // constructing a temporary.
173  MemRegionManager &MRMgr = Eng.getSValBuilder().getRegionManager();
174  return MRMgr.getCXXTempObjectRegion(CE, LCtx);
175}
176
177void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE,
178                                       ExplodedNode *Pred,
179                                       ExplodedNodeSet &destNodes) {
180  const LocationContext *LCtx = Pred->getLocationContext();
181  ProgramStateRef State = Pred->getState();
182
183  const MemRegion *Target = nullptr;
184
185  // FIXME: Handle arrays, which run the same constructor for every element.
186  // For now, we just run the first constructor (which should still invalidate
187  // the entire array).
188
189  switch (CE->getConstructionKind()) {
190  case CXXConstructExpr::CK_Complete: {
191    Target = getRegionForConstructedObject(CE, Pred, *this, currStmtIdx);
192    break;
193  }
194  case CXXConstructExpr::CK_VirtualBase:
195    // Make sure we are not calling virtual base class initializers twice.
196    // Only the most-derived object should initialize virtual base classes.
197    if (const Stmt *Outer = LCtx->getCurrentStackFrame()->getCallSite()) {
198      const CXXConstructExpr *OuterCtor = dyn_cast<CXXConstructExpr>(Outer);
199      if (OuterCtor) {
200        switch (OuterCtor->getConstructionKind()) {
201        case CXXConstructExpr::CK_NonVirtualBase:
202        case CXXConstructExpr::CK_VirtualBase:
203          // Bail out!
204          destNodes.Add(Pred);
205          return;
206        case CXXConstructExpr::CK_Complete:
207        case CXXConstructExpr::CK_Delegating:
208          break;
209        }
210      }
211    }
212    // FALLTHROUGH
213  case CXXConstructExpr::CK_NonVirtualBase:
214  case CXXConstructExpr::CK_Delegating: {
215    const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
216    Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor,
217                                              LCtx->getCurrentStackFrame());
218    SVal ThisVal = State->getSVal(ThisPtr);
219
220    if (CE->getConstructionKind() == CXXConstructExpr::CK_Delegating) {
221      Target = ThisVal.getAsRegion();
222    } else {
223      // Cast to the base type.
224      bool IsVirtual =
225        (CE->getConstructionKind() == CXXConstructExpr::CK_VirtualBase);
226      SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, CE->getType(),
227                                                         IsVirtual);
228      Target = BaseVal.getAsRegion();
229    }
230    break;
231  }
232  }
233
234  CallEventManager &CEMgr = getStateManager().getCallEventManager();
235  CallEventRef<CXXConstructorCall> Call =
236    CEMgr.getCXXConstructorCall(CE, Target, State, LCtx);
237
238  ExplodedNodeSet DstPreVisit;
239  getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, CE, *this);
240
241  ExplodedNodeSet PreInitialized;
242  {
243    StmtNodeBuilder Bldr(DstPreVisit, PreInitialized, *currBldrCtx);
244    if (CE->requiresZeroInitialization()) {
245      // Type of the zero doesn't matter.
246      SVal ZeroVal = svalBuilder.makeZeroVal(getContext().CharTy);
247
248      for (ExplodedNodeSet::iterator I = DstPreVisit.begin(),
249                                     E = DstPreVisit.end();
250           I != E; ++I) {
251        ProgramStateRef State = (*I)->getState();
252        // FIXME: Once we properly handle constructors in new-expressions, we'll
253        // need to invalidate the region before setting a default value, to make
254        // sure there aren't any lingering bindings around. This probably needs
255        // to happen regardless of whether or not the object is zero-initialized
256        // to handle random fields of a placement-initialized object picking up
257        // old bindings. We might only want to do it when we need to, though.
258        // FIXME: This isn't actually correct for arrays -- we need to zero-
259        // initialize the entire array, not just the first element -- but our
260        // handling of arrays everywhere else is weak as well, so this shouldn't
261        // actually make things worse. Placement new makes this tricky as well,
262        // since it's then possible to be initializing one part of a multi-
263        // dimensional array.
264        State = State->bindDefault(loc::MemRegionVal(Target), ZeroVal);
265        Bldr.generateNode(CE, *I, State, /*tag=*/nullptr,
266                          ProgramPoint::PreStmtKind);
267      }
268    }
269  }
270
271  ExplodedNodeSet DstPreCall;
272  getCheckerManager().runCheckersForPreCall(DstPreCall, PreInitialized,
273                                            *Call, *this);
274
275  ExplodedNodeSet DstEvaluated;
276  StmtNodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx);
277
278  bool IsArray = isa<ElementRegion>(Target);
279  if (CE->getConstructor()->isTrivial() &&
280      CE->getConstructor()->isCopyOrMoveConstructor() &&
281      !IsArray) {
282    // FIXME: Handle other kinds of trivial constructors as well.
283    for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
284         I != E; ++I)
285      performTrivialCopy(Bldr, *I, *Call);
286
287  } else {
288    for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
289         I != E; ++I)
290      defaultEvalCall(Bldr, *I, *Call);
291  }
292
293  ExplodedNodeSet DstPostCall;
294  getCheckerManager().runCheckersForPostCall(DstPostCall, DstEvaluated,
295                                             *Call, *this);
296  getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, CE, *this);
297}
298
299void ExprEngine::VisitCXXDestructor(QualType ObjectType,
300                                    const MemRegion *Dest,
301                                    const Stmt *S,
302                                    bool IsBaseDtor,
303                                    ExplodedNode *Pred,
304                                    ExplodedNodeSet &Dst) {
305  const LocationContext *LCtx = Pred->getLocationContext();
306  ProgramStateRef State = Pred->getState();
307
308  // FIXME: We need to run the same destructor on every element of the array.
309  // This workaround will just run the first destructor (which will still
310  // invalidate the entire array).
311  SVal DestVal = UnknownVal();
312  if (Dest)
313    DestVal = loc::MemRegionVal(Dest);
314  DestVal = makeZeroElementRegion(State, DestVal, ObjectType);
315  Dest = DestVal.getAsRegion();
316
317  const CXXRecordDecl *RecordDecl = ObjectType->getAsCXXRecordDecl();
318  assert(RecordDecl && "Only CXXRecordDecls should have destructors");
319  const CXXDestructorDecl *DtorDecl = RecordDecl->getDestructor();
320
321  CallEventManager &CEMgr = getStateManager().getCallEventManager();
322  CallEventRef<CXXDestructorCall> Call =
323    CEMgr.getCXXDestructorCall(DtorDecl, S, Dest, IsBaseDtor, State, LCtx);
324
325  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
326                                Call->getSourceRange().getBegin(),
327                                "Error evaluating destructor");
328
329  ExplodedNodeSet DstPreCall;
330  getCheckerManager().runCheckersForPreCall(DstPreCall, Pred,
331                                            *Call, *this);
332
333  ExplodedNodeSet DstInvalidated;
334  StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);
335  for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
336       I != E; ++I)
337    defaultEvalCall(Bldr, *I, *Call);
338
339  ExplodedNodeSet DstPostCall;
340  getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated,
341                                             *Call, *this);
342}
343
344void ExprEngine::VisitCXXNewAllocatorCall(const CXXNewExpr *CNE,
345                                          ExplodedNode *Pred,
346                                          ExplodedNodeSet &Dst) {
347  ProgramStateRef State = Pred->getState();
348  const LocationContext *LCtx = Pred->getLocationContext();
349  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
350                                CNE->getStartLoc(),
351                                "Error evaluating New Allocator Call");
352  CallEventManager &CEMgr = getStateManager().getCallEventManager();
353  CallEventRef<CXXAllocatorCall> Call =
354    CEMgr.getCXXAllocatorCall(CNE, State, LCtx);
355
356  ExplodedNodeSet DstPreCall;
357  getCheckerManager().runCheckersForPreCall(DstPreCall, Pred,
358                                            *Call, *this);
359
360  ExplodedNodeSet DstInvalidated;
361  StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);
362  for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
363       I != E; ++I)
364    defaultEvalCall(Bldr, *I, *Call);
365  getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated,
366                                             *Call, *this);
367}
368
369
370void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
371                                   ExplodedNodeSet &Dst) {
372  // FIXME: Much of this should eventually migrate to CXXAllocatorCall.
373  // Also, we need to decide how allocators actually work -- they're not
374  // really part of the CXXNewExpr because they happen BEFORE the
375  // CXXConstructExpr subexpression. See PR12014 for some discussion.
376
377  unsigned blockCount = currBldrCtx->blockCount();
378  const LocationContext *LCtx = Pred->getLocationContext();
379  DefinedOrUnknownSVal symVal = UnknownVal();
380  FunctionDecl *FD = CNE->getOperatorNew();
381
382  bool IsStandardGlobalOpNewFunction = false;
383  if (FD && !isa<CXXMethodDecl>(FD) && !FD->isVariadic()) {
384    if (FD->getNumParams() == 2) {
385      QualType T = FD->getParamDecl(1)->getType();
386      if (const IdentifierInfo *II = T.getBaseTypeIdentifier())
387        // NoThrow placement new behaves as a standard new.
388        IsStandardGlobalOpNewFunction = II->getName().equals("nothrow_t");
389    }
390    else
391      // Placement forms are considered non-standard.
392      IsStandardGlobalOpNewFunction = (FD->getNumParams() == 1);
393  }
394
395  // We assume all standard global 'operator new' functions allocate memory in
396  // heap. We realize this is an approximation that might not correctly model
397  // a custom global allocator.
398  if (IsStandardGlobalOpNewFunction)
399    symVal = svalBuilder.getConjuredHeapSymbolVal(CNE, LCtx, blockCount);
400  else
401    symVal = svalBuilder.conjureSymbolVal(nullptr, CNE, LCtx, CNE->getType(),
402                                          blockCount);
403
404  ProgramStateRef State = Pred->getState();
405  CallEventManager &CEMgr = getStateManager().getCallEventManager();
406  CallEventRef<CXXAllocatorCall> Call =
407    CEMgr.getCXXAllocatorCall(CNE, State, LCtx);
408
409  // Invalidate placement args.
410  // FIXME: Once we figure out how we want allocators to work,
411  // we should be using the usual pre-/(default-)eval-/post-call checks here.
412  State = Call->invalidateRegions(blockCount);
413  if (!State)
414    return;
415
416  // If this allocation function is not declared as non-throwing, failures
417  // /must/ be signalled by exceptions, and thus the return value will never be
418  // NULL. -fno-exceptions does not influence this semantics.
419  // FIXME: GCC has a -fcheck-new option, which forces it to consider the case
420  // where new can return NULL. If we end up supporting that option, we can
421  // consider adding a check for it here.
422  // C++11 [basic.stc.dynamic.allocation]p3.
423  if (FD) {
424    QualType Ty = FD->getType();
425    if (const FunctionProtoType *ProtoType = Ty->getAs<FunctionProtoType>())
426      if (!ProtoType->isNothrow(getContext()))
427        State = State->assume(symVal, true);
428  }
429
430  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
431
432  if (CNE->isArray()) {
433    // FIXME: allocating an array requires simulating the constructors.
434    // For now, just return a symbolicated region.
435    const MemRegion *NewReg = symVal.castAs<loc::MemRegionVal>().getRegion();
436    QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType();
437    const ElementRegion *EleReg =
438      getStoreManager().GetElementZeroRegion(NewReg, ObjTy);
439    State = State->BindExpr(CNE, Pred->getLocationContext(),
440                            loc::MemRegionVal(EleReg));
441    Bldr.generateNode(CNE, Pred, State);
442    return;
443  }
444
445  // FIXME: Once we have proper support for CXXConstructExprs inside
446  // CXXNewExpr, we need to make sure that the constructed object is not
447  // immediately invalidated here. (The placement call should happen before
448  // the constructor call anyway.)
449  SVal Result = symVal;
450  if (FD && FD->isReservedGlobalPlacementOperator()) {
451    // Non-array placement new should always return the placement location.
452    SVal PlacementLoc = State->getSVal(CNE->getPlacementArg(0), LCtx);
453    Result = svalBuilder.evalCast(PlacementLoc, CNE->getType(),
454                                  CNE->getPlacementArg(0)->getType());
455  }
456
457  // Bind the address of the object, then check to see if we cached out.
458  State = State->BindExpr(CNE, LCtx, Result);
459  ExplodedNode *NewN = Bldr.generateNode(CNE, Pred, State);
460  if (!NewN)
461    return;
462
463  // If the type is not a record, we won't have a CXXConstructExpr as an
464  // initializer. Copy the value over.
465  if (const Expr *Init = CNE->getInitializer()) {
466    if (!isa<CXXConstructExpr>(Init)) {
467      assert(Bldr.getResults().size() == 1);
468      Bldr.takeNodes(NewN);
469      evalBind(Dst, CNE, NewN, Result, State->getSVal(Init, LCtx),
470               /*FirstInit=*/IsStandardGlobalOpNewFunction);
471    }
472  }
473}
474
475void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE,
476                                    ExplodedNode *Pred, ExplodedNodeSet &Dst) {
477  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
478  ProgramStateRef state = Pred->getState();
479  Bldr.generateNode(CDE, Pred, state);
480}
481
482void ExprEngine::VisitCXXCatchStmt(const CXXCatchStmt *CS,
483                                   ExplodedNode *Pred,
484                                   ExplodedNodeSet &Dst) {
485  const VarDecl *VD = CS->getExceptionDecl();
486  if (!VD) {
487    Dst.Add(Pred);
488    return;
489  }
490
491  const LocationContext *LCtx = Pred->getLocationContext();
492  SVal V = svalBuilder.conjureSymbolVal(CS, LCtx, VD->getType(),
493                                        currBldrCtx->blockCount());
494  ProgramStateRef state = Pred->getState();
495  state = state->bindLoc(state->getLValue(VD, LCtx), V);
496
497  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
498  Bldr.generateNode(CS, Pred, state);
499}
500
501void ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
502                                    ExplodedNodeSet &Dst) {
503  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
504
505  // Get the this object region from StoreManager.
506  const LocationContext *LCtx = Pred->getLocationContext();
507  const MemRegion *R =
508    svalBuilder.getRegionManager().getCXXThisRegion(
509                                  getContext().getCanonicalType(TE->getType()),
510                                                    LCtx);
511
512  ProgramStateRef state = Pred->getState();
513  SVal V = state->getSVal(loc::MemRegionVal(R));
514  Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V));
515}
516