ExprEngineCXX.cpp revision 263508
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  // 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())
98    return LValue;
99
100  SValBuilder &SVB = State->getStateManager().getSValBuilder();
101  ASTContext &Ctx = SVB.getContext();
102
103  while (const ArrayType *AT = Ctx.getAsArrayType(Ty)) {
104    Ty = AT->getElementType();
105    LValue = State->getLValue(Ty, SVB.makeZeroArrayIndex(), LValue);
106  }
107
108  return LValue;
109}
110
111void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE,
112                                       ExplodedNode *Pred,
113                                       ExplodedNodeSet &destNodes) {
114  const LocationContext *LCtx = Pred->getLocationContext();
115  ProgramStateRef State = Pred->getState();
116
117  const MemRegion *Target = 0;
118
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).
122
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];
130
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();
140            }
141          }
142        }
143      }
144
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());
149
150        const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
151        Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor,
152                                                  LCtx->getCurrentStackFrame());
153        SVal ThisVal = State->getSVal(ThisPtr);
154
155        const ValueDecl *Field;
156        SVal FieldVal;
157        if (Init->isIndirectMemberInitializer()) {
158          Field = Init->getIndirectMember();
159          FieldVal = State->getLValue(Init->getIndirectMember(), ThisVal);
160        } else {
161          Field = Init->getMember();
162          FieldVal = State->getLValue(Init->getMember(), ThisVal);
163        }
164
165        QualType Ty = Field->getType();
166        FieldVal = makeZeroElementRegion(State, FieldVal, Ty);
167        Target = FieldVal.getAsRegion();
168      }
169
170      // FIXME: This will eventually need to handle new-expressions as well.
171      // Don't forget to update the pre-constructor initialization code below.
172    }
173
174    // If we couldn't find an existing region to construct into, assume we're
175    // constructing a temporary.
176    if (!Target) {
177      MemRegionManager &MRMgr = getSValBuilder().getRegionManager();
178      Target = MRMgr.getCXXTempObjectRegion(CE, LCtx);
179    }
180
181    break;
182  }
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);
188      if (OuterCtor) {
189        switch (OuterCtor->getConstructionKind()) {
190        case CXXConstructExpr::CK_NonVirtualBase:
191        case CXXConstructExpr::CK_VirtualBase:
192          // Bail out!
193          destNodes.Add(Pred);
194          return;
195        case CXXConstructExpr::CK_Complete:
196        case CXXConstructExpr::CK_Delegating:
197          break;
198        }
199      }
200    }
201    // FALLTHROUGH
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);
208
209    if (CE->getConstructionKind() == CXXConstructExpr::CK_Delegating) {
210      Target = ThisVal.getAsRegion();
211    } else {
212      // Cast to the base type.
213      bool IsVirtual =
214        (CE->getConstructionKind() == CXXConstructExpr::CK_VirtualBase);
215      SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, CE->getType(),
216                                                         IsVirtual);
217      Target = BaseVal.getAsRegion();
218    }
219    break;
220  }
221  }
222
223  CallEventManager &CEMgr = getStateManager().getCallEventManager();
224  CallEventRef<CXXConstructorCall> Call =
225    CEMgr.getCXXConstructorCall(CE, Target, State, LCtx);
226
227  ExplodedNodeSet DstPreVisit;
228  getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, CE, *this);
229
230  ExplodedNodeSet PreInitialized;
231  {
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);
236
237      for (ExplodedNodeSet::iterator I = DstPreVisit.begin(),
238                                     E = DstPreVisit.end();
239           I != E; ++I) {
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);
255      }
256    }
257  }
258
259  ExplodedNodeSet DstPreCall;
260  getCheckerManager().runCheckersForPreCall(DstPreCall, PreInitialized,
261                                            *Call, *this);
262
263  ExplodedNodeSet DstEvaluated;
264  StmtNodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx);
265
266  bool IsArray = isa<ElementRegion>(Target);
267  if (CE->getConstructor()->isTrivial() &&
268      CE->getConstructor()->isCopyOrMoveConstructor() &&
269      !IsArray) {
270    // FIXME: Handle other kinds of trivial constructors as well.
271    for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
272         I != E; ++I)
273      performTrivialCopy(Bldr, *I, *Call);
274
275  } else {
276    for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
277         I != E; ++I)
278      defaultEvalCall(Bldr, *I, *Call);
279  }
280
281  ExplodedNodeSet DstPostCall;
282  getCheckerManager().runCheckersForPostCall(DstPostCall, DstEvaluated,
283                                             *Call, *this);
284  getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, CE, *this);
285}
286
287void ExprEngine::VisitCXXDestructor(QualType ObjectType,
288                                    const MemRegion *Dest,
289                                    const Stmt *S,
290                                    bool IsBaseDtor,
291                                    ExplodedNode *Pred,
292                                    ExplodedNodeSet &Dst) {
293  const LocationContext *LCtx = Pred->getLocationContext();
294  ProgramStateRef State = Pred->getState();
295
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();
300  if (Dest)
301    DestVal = loc::MemRegionVal(Dest);
302  DestVal = makeZeroElementRegion(State, DestVal, ObjectType);
303  Dest = DestVal.getAsRegion();
304
305  const CXXRecordDecl *RecordDecl = ObjectType->getAsCXXRecordDecl();
306  assert(RecordDecl && "Only CXXRecordDecls should have destructors");
307  const CXXDestructorDecl *DtorDecl = RecordDecl->getDestructor();
308
309  CallEventManager &CEMgr = getStateManager().getCallEventManager();
310  CallEventRef<CXXDestructorCall> Call =
311    CEMgr.getCXXDestructorCall(DtorDecl, S, Dest, IsBaseDtor, State, LCtx);
312
313  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
314                                Call->getSourceRange().getBegin(),
315                                "Error evaluating destructor");
316
317  ExplodedNodeSet DstPreCall;
318  getCheckerManager().runCheckersForPreCall(DstPreCall, Pred,
319                                            *Call, *this);
320
321  ExplodedNodeSet DstInvalidated;
322  StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);
323  for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
324       I != E; ++I)
325    defaultEvalCall(Bldr, *I, *Call);
326
327  ExplodedNodeSet DstPostCall;
328  getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated,
329                                             *Call, *this);
330}
331
332void 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.
338
339  unsigned blockCount = currBldrCtx->blockCount();
340  const LocationContext *LCtx = Pred->getLocationContext();
341  DefinedOrUnknownSVal symVal = UnknownVal();
342  FunctionDecl *FD = CNE->getOperatorNew();
343
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");
351    }
352    else
353      // Placement forms are considered non-standard.
354      IsStandardGlobalOpNewFunction = (FD->getNumParams() == 1);
355  }
356
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);
362  else
363    symVal = svalBuilder.conjureSymbolVal(0, CNE, LCtx, CNE->getType(),
364                                          blockCount);
365
366  ProgramStateRef State = Pred->getState();
367  CallEventManager &CEMgr = getStateManager().getCallEventManager();
368  CallEventRef<CXXAllocatorCall> Call =
369    CEMgr.getCXXAllocatorCall(CNE, State, LCtx);
370
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);
375  if (!State)
376    return;
377
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.
385  if (FD) {
386    QualType Ty = FD->getType();
387    if (const FunctionProtoType *ProtoType = Ty->getAs<FunctionProtoType>())
388      if (!ProtoType->isNothrow(getContext()))
389        State = State->assume(symVal, true);
390  }
391
392  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
393
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);
404    return;
405  }
406
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());
417  }
418
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);
422  if (!NewN)
423    return;
424
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);
433    }
434  }
435}
436
437void 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);
442}
443
444void ExprEngine::VisitCXXCatchStmt(const CXXCatchStmt *CS,
445                                   ExplodedNode *Pred,
446                                   ExplodedNodeSet &Dst) {
447  const VarDecl *VD = CS->getExceptionDecl();
448  if (!VD) {
449    Dst.Add(Pred);
450    return;
451  }
452
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);
458
459  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
460  Bldr.generateNode(CS, Pred, state);
461}
462
463void ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
464                                    ExplodedNodeSet &Dst) {
465  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
466
467  // Get the this object region from StoreManager.
468  const LocationContext *LCtx = Pred->getLocationContext();
469  const MemRegion *R =
470    svalBuilder.getRegionManager().getCXXThisRegion(
471                                  getContext().getCanonicalType(TE->getType()),
472                                                    LCtx);
473
474  ProgramStateRef state = Pred->getState();
475  SVal V = state->getSVal(loc::MemRegionVal(R));
476  Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V));
477}
478