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