Clang Project

clang_source_code/lib/StaticAnalyzer/Core/ExprEngineC.cpp
1//=-- ExprEngineC.cpp - ExprEngine support for C expressions ----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9//  This file defines ExprEngine's support for C expressions.
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/AST/ExprCXX.h"
14#include "clang/AST/DeclCXX.h"
15#include "clang/StaticAnalyzer/Core/CheckerManager.h"
16#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
17
18using namespace clang;
19using namespace ento;
20using llvm::APSInt;
21
22/// Optionally conjure and return a symbol for offset when processing
23/// an expression \p Expression.
24/// If \p Other is a location, conjure a symbol for \p Symbol
25/// (offset) if it is unknown so that memory arithmetic always
26/// results in an ElementRegion.
27/// \p Count The number of times the current basic block was visited.
28static SVal conjureOffsetSymbolOnLocation(
29    SVal SymbolSVal OtherExprExpressionSValBuilder &svalBuilder,
30    unsigned Countconst LocationContext *LCtx) {
31  QualType Ty = Expression->getType();
32  if (Other.getAs<Loc>() &&
33      Ty->isIntegralOrEnumerationType() &&
34      Symbol.isUnknown()) {
35    return svalBuilder.conjureSymbolVal(ExpressionLCtxTyCount);
36  }
37  return Symbol;
38}
39
40void ExprEngine::VisitBinaryOperator(const BinaryOperatorB,
41                                     ExplodedNode *Pred,
42                                     ExplodedNodeSet &Dst) {
43
44  Expr *LHS = B->getLHS()->IgnoreParens();
45  Expr *RHS = B->getRHS()->IgnoreParens();
46
47  // FIXME: Prechecks eventually go in ::Visit().
48  ExplodedNodeSet CheckedSet;
49  ExplodedNodeSet Tmp2;
50  getCheckerManager().runCheckersForPreStmt(CheckedSetPredB*this);
51
52  // With both the LHS and RHS evaluated, process the operation itself.
53  for (ExplodedNodeSet::iterator it=CheckedSet.begin(), ei=CheckedSet.end();
54         it != ei; ++it) {
55
56    ProgramStateRef state = (*it)->getState();
57    const LocationContext *LCtx = (*it)->getLocationContext();
58    SVal LeftV = state->getSVal(LHS, LCtx);
59    SVal RightV = state->getSVal(RHS, LCtx);
60
61    BinaryOperator::Opcode Op = B->getOpcode();
62
63    if (Op == BO_Assign) {
64      // EXPERIMENTAL: "Conjured" symbols.
65      // FIXME: Handle structs.
66      if (RightV.isUnknown()) {
67        unsigned Count = currBldrCtx->blockCount();
68        RightV = svalBuilder.conjureSymbolVal(nullptr, B->getRHS(), LCtx,
69                                              Count);
70      }
71      // Simulate the effects of a "store":  bind the value of the RHS
72      // to the L-Value represented by the LHS.
73      SVal ExprVal = B->isGLValue() ? LeftV : RightV;
74      evalStore(Tmp2, B, LHS, *it, state->BindExpr(B, LCtx, ExprVal),
75                LeftV, RightV);
76      continue;
77    }
78
79    if (!B->isAssignmentOp()) {
80      StmtNodeBuilder Bldr(*it, Tmp2, *currBldrCtx);
81
82      if (B->isAdditiveOp()) {
83        // TODO: This can be removed after we enable history tracking with
84        // SymSymExpr.
85        unsigned Count = currBldrCtx->blockCount();
86        RightV = conjureOffsetSymbolOnLocation(
87            RightV, LeftV, RHS, svalBuilder, Count, LCtx);
88        LeftV = conjureOffsetSymbolOnLocation(
89            LeftV, RightV, LHS, svalBuilder, Count, LCtx);
90      }
91
92      // Although we don't yet model pointers-to-members, we do need to make
93      // sure that the members of temporaries have a valid 'this' pointer for
94      // other checks.
95      if (B->getOpcode() == BO_PtrMemD)
96        state = createTemporaryRegionIfNeeded(state, LCtx, LHS);
97
98      // Process non-assignments except commas or short-circuited
99      // logical expressions (LAnd and LOr).
100      SVal Result = evalBinOp(state, Op, LeftV, RightV, B->getType());
101      if (!Result.isUnknown()) {
102        state = state->BindExpr(B, LCtx, Result);
103      }
104
105      Bldr.generateNode(B, *it, state);
106      continue;
107    }
108
109    isCompoundAssignmentOp()", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 109, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert (B->isCompoundAssignmentOp());
110
111    switch (Op) {
112      default:
113        llvm_unreachable("Invalid opcode for compound assignment.");
114      case BO_MulAssign: Op = BO_Mul; break;
115      case BO_DivAssign: Op = BO_Div; break;
116      case BO_RemAssign: Op = BO_Rem; break;
117      case BO_AddAssign: Op = BO_Add; break;
118      case BO_SubAssign: Op = BO_Sub; break;
119      case BO_ShlAssign: Op = BO_Shl; break;
120      case BO_ShrAssign: Op = BO_Shr; break;
121      case BO_AndAssign: Op = BO_And; break;
122      case BO_XorAssign: Op = BO_Xor; break;
123      case BO_OrAssign:  Op = BO_Or;  break;
124    }
125
126    // Perform a load (the LHS).  This performs the checks for
127    // null dereferences, and so on.
128    ExplodedNodeSet Tmp;
129    SVal location = LeftV;
130    evalLoad(Tmp, B, LHS, *it, state, location);
131
132    for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E;
133         ++I) {
134
135      state = (*I)->getState();
136      const LocationContext *LCtx = (*I)->getLocationContext();
137      SVal V = state->getSVal(LHS, LCtx);
138
139      // Get the computation type.
140      QualType CTy =
141        cast<CompoundAssignOperator>(B)->getComputationResultType();
142      CTy = getContext().getCanonicalType(CTy);
143
144      QualType CLHSTy =
145        cast<CompoundAssignOperator>(B)->getComputationLHSType();
146      CLHSTy = getContext().getCanonicalType(CLHSTy);
147
148      QualType LTy = getContext().getCanonicalType(LHS->getType());
149
150      // Promote LHS.
151      V = svalBuilder.evalCast(V, CLHSTy, LTy);
152
153      // Compute the result of the operation.
154      SVal Result = svalBuilder.evalCast(evalBinOp(state, Op, V, RightV, CTy),
155                                         B->getType(), CTy);
156
157      // EXPERIMENTAL: "Conjured" symbols.
158      // FIXME: Handle structs.
159
160      SVal LHSVal;
161
162      if (Result.isUnknown()) {
163        // The symbolic value is actually for the type of the left-hand side
164        // expression, not the computation type, as this is the value the
165        // LValue on the LHS will bind to.
166        LHSVal = svalBuilder.conjureSymbolVal(nullptr, B->getRHS(), LCtx, LTy,
167                                              currBldrCtx->blockCount());
168        // However, we need to convert the symbol to the computation type.
169        Result = svalBuilder.evalCast(LHSVal, CTy, LTy);
170      }
171      else {
172        // The left-hand side may bind to a different value then the
173        // computation type.
174        LHSVal = svalBuilder.evalCast(Result, LTy, CTy);
175      }
176
177      // In C++, assignment and compound assignment operators return an
178      // lvalue.
179      if (B->isGLValue())
180        state = state->BindExpr(B, LCtx, location);
181      else
182        state = state->BindExpr(B, LCtx, Result);
183
184      evalStore(Tmp2, B, LHS, *I, state, location, LHSVal);
185    }
186  }
187
188  // FIXME: postvisits eventually go in ::Visit()
189  getCheckerManager().runCheckersForPostStmt(Dst, Tmp2, B, *this);
190}
191
192void ExprEngine::VisitBlockExpr(const BlockExpr *BEExplodedNode *Pred,
193                                ExplodedNodeSet &Dst) {
194
195  CanQualType T = getContext().getCanonicalType(BE->getType());
196
197  const BlockDecl *BD = BE->getBlockDecl();
198  // Get the value of the block itself.
199  SVal V = svalBuilder.getBlockPointer(BDT,
200                                       Pred->getLocationContext(),
201                                       currBldrCtx->blockCount());
202
203  ProgramStateRef State = Pred->getState();
204
205  // If we created a new MemRegion for the block, we should explicitly bind
206  // the captured variables.
207  if (const BlockDataRegion *BDR =
208      dyn_cast_or_null<BlockDataRegion>(V.getAsRegion())) {
209
210    BlockDataRegion::referenced_vars_iterator I = BDR->referenced_vars_begin(),
211                                              E = BDR->referenced_vars_end();
212
213    auto CI = BD->capture_begin();
214    auto CE = BD->capture_end();
215    for (; I != E; ++I) {
216      const VarRegion *capturedR = I.getCapturedRegion();
217      const VarRegion *originalR = I.getOriginalRegion();
218
219      // If the capture had a copy expression, use the result of evaluating
220      // that expression, otherwise use the original value.
221      // We rely on the invariant that the block declaration's capture variables
222      // are a prefix of the BlockDataRegion's referenced vars (which may include
223      // referenced globals, etc.) to enable fast lookup of the capture for a
224      // given referenced var.
225      const Expr *copyExpr = nullptr;
226      if (CI != CE) {
227        getVariable() == capturedR->getDecl()", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 227, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(CI->getVariable() == capturedR->getDecl());
228        copyExpr = CI->getCopyExpr();
229        CI++;
230      }
231
232      if (capturedR != originalR) {
233        SVal originalV;
234        const LocationContext *LCtx = Pred->getLocationContext();
235        if (copyExpr) {
236          originalV = State->getSVal(copyExpr, LCtx);
237        } else {
238          originalV = State->getSVal(loc::MemRegionVal(originalR));
239        }
240        State = State->bindLoc(loc::MemRegionVal(capturedR), originalV, LCtx);
241      }
242    }
243  }
244
245  ExplodedNodeSet Tmp;
246  StmtNodeBuilder Bldr(PredTmp, *currBldrCtx);
247  Bldr.generateNode(BE, Pred,
248                    State->BindExpr(BE, Pred->getLocationContext(), V),
249                    nullptr, ProgramPoint::PostLValueKind);
250
251  // FIXME: Move all post/pre visits to ::Visit().
252  getCheckerManager().runCheckersForPostStmt(DstTmpBE*this);
253}
254
255ProgramStateRef ExprEngine::handleLValueBitCast(
256    ProgramStateRef stateconst ExprExconst LocationContextLCtx,
257    QualType TQualType ExTyconst CastExprCastEStmtNodeBuilderBldr,
258    ExplodedNodePred) {
259  if (T->isLValueReferenceType()) {
260    getType()->isLValueReferenceType()", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 260, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(!CastE->getType()->isLValueReferenceType());
261    ExTy = getContext().getLValueReferenceType(ExTy);
262  } else if (T->isRValueReferenceType()) {
263    getType()->isRValueReferenceType()", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 263, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(!CastE->getType()->isRValueReferenceType());
264    ExTy = getContext().getRValueReferenceType(ExTy);
265  }
266  // Delegate to SValBuilder to process.
267  SVal OrigV = state->getSVal(Ex, LCtx);
268  SVal V = svalBuilder.evalCast(OrigVTExTy);
269  // Negate the result if we're treating the boolean as a signed i1
270  if (CastE->getCastKind() == CK_BooleanToSignedIntegral)
271    V = evalMinus(V);
272  state = state->BindExpr(CastE, LCtx, V);
273  if (V.isUnknown() && !OrigV.isUnknown()) {
274    state = escapeValue(state, OrigV, PSK_EscapeOther);
275  }
276  Bldr.generateNode(CastE, Pred, state);
277
278  return state;
279}
280
281ProgramStateRef ExprEngine::handleLVectorSplat(
282    ProgramStateRef stateconst LocationContextLCtxconst CastExprCastE,
283    StmtNodeBuilder &BldrExplodedNodePred) {
284  // Recover some path sensitivity by conjuring a new value.
285  QualType resultType = CastE->getType();
286  if (CastE->isGLValue())
287    resultType = getContext().getPointerType(resultType);
288  SVal result = svalBuilder.conjureSymbolVal(nullptrCastELCtx,
289                                             resultType,
290                                             currBldrCtx->blockCount());
291  state = state->BindExpr(CastE, LCtx, result);
292  Bldr.generateNode(CastE, Pred, state);
293
294  return state;
295}
296
297void ExprEngine::VisitCast(const CastExpr *CastEconst Expr *Ex,
298                           ExplodedNode *PredExplodedNodeSet &Dst) {
299
300  ExplodedNodeSet dstPreStmt;
301  getCheckerManager().runCheckersForPreStmt(dstPreStmtPredCastE*this);
302
303  if (CastE->getCastKind() == CK_LValueToRValue) {
304    for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end();
305         I!=E; ++I) {
306      ExplodedNode *subExprNode = *I;
307      ProgramStateRef state = subExprNode->getState();
308      const LocationContext *LCtx = subExprNode->getLocationContext();
309      evalLoad(Dst, CastE, CastE, subExprNode, state, state->getSVal(Ex, LCtx));
310    }
311    return;
312  }
313
314  // All other casts.
315  QualType T = CastE->getType();
316  QualType ExTy = Ex->getType();
317
318  if (const ExplicitCastExpr *ExCast=dyn_cast_or_null<ExplicitCastExpr>(CastE))
319    T = ExCast->getTypeAsWritten();
320
321  StmtNodeBuilder Bldr(dstPreStmtDst, *currBldrCtx);
322  for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end();
323       I != E; ++I) {
324
325    Pred = *I;
326    ProgramStateRef state = Pred->getState();
327    const LocationContext *LCtx = Pred->getLocationContext();
328
329    switch (CastE->getCastKind()) {
330      case CK_LValueToRValue:
331        llvm_unreachable("LValueToRValue casts handled earlier.");
332      case CK_ToVoid:
333        continue;
334        // The analyzer doesn't do anything special with these casts,
335        // since it understands retain/release semantics already.
336      case CK_ARCProduceObject:
337      case CK_ARCConsumeObject:
338      case CK_ARCReclaimReturnedObject:
339      case CK_ARCExtendBlockObject: // Fall-through.
340      case CK_CopyAndAutoreleaseBlockObject:
341        // The analyser can ignore atomic casts for now, although some future
342        // checkers may want to make certain that you're not modifying the same
343        // value through atomic and nonatomic pointers.
344      case CK_AtomicToNonAtomic:
345      case CK_NonAtomicToAtomic:
346        // True no-ops.
347      case CK_NoOp:
348      case CK_ConstructorConversion:
349      case CK_UserDefinedConversion:
350      case CK_FunctionToPointerDecay:
351      case CK_BuiltinFnToFnPtr: {
352        // Copy the SVal of Ex to CastE.
353        ProgramStateRef state = Pred->getState();
354        const LocationContext *LCtx = Pred->getLocationContext();
355        SVal V = state->getSVal(Ex, LCtx);
356        state = state->BindExpr(CastE, LCtx, V);
357        Bldr.generateNode(CastE, Pred, state);
358        continue;
359      }
360      case CK_MemberPointerToBoolean:
361      case CK_PointerToBoolean: {
362        SVal V = state->getSVal(Ex, LCtx);
363        auto PTMSV = V.getAs<nonloc::PointerToMember>();
364        if (PTMSV)
365          V = svalBuilder.makeTruthVal(!PTMSV->isNullMemberPointer(), ExTy);
366        if (V.isUndef() || PTMSV) {
367          state = state->BindExpr(CastE, LCtx, V);
368          Bldr.generateNode(CastE, Pred, state);
369          continue;
370        }
371        // Explicitly proceed with default handler for this case cascade.
372        state =
373            handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred);
374        continue;
375      }
376      case CK_Dependent:
377      case CK_ArrayToPointerDecay:
378      case CK_BitCast:
379      case CK_AddressSpaceConversion:
380      case CK_BooleanToSignedIntegral:
381      case CK_NullToPointer:
382      case CK_IntegralToPointer:
383      case CK_PointerToIntegral: {
384        SVal V = state->getSVal(Ex, LCtx);
385        if (V.getAs<nonloc::PointerToMember>()) {
386          state = state->BindExpr(CastE, LCtx, UnknownVal());
387          Bldr.generateNode(CastE, Pred, state);
388          continue;
389        }
390        // Explicitly proceed with default handler for this case cascade.
391        state =
392            handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred);
393        continue;
394      }
395      case CK_IntegralToBoolean:
396      case CK_IntegralToFloating:
397      case CK_FloatingToIntegral:
398      case CK_FloatingToBoolean:
399      case CK_FloatingCast:
400      case CK_FloatingRealToComplex:
401      case CK_FloatingComplexToReal:
402      case CK_FloatingComplexToBoolean:
403      case CK_FloatingComplexCast:
404      case CK_FloatingComplexToIntegralComplex:
405      case CK_IntegralRealToComplex:
406      case CK_IntegralComplexToReal:
407      case CK_IntegralComplexToBoolean:
408      case CK_IntegralComplexCast:
409      case CK_IntegralComplexToFloatingComplex:
410      case CK_CPointerToObjCPointerCast:
411      case CK_BlockPointerToObjCPointerCast:
412      case CK_AnyPointerToBlockPointerCast:
413      case CK_ObjCObjectLValueCast:
414      case CK_ZeroToOCLOpaqueType:
415      case CK_IntToOCLSampler:
416      case CK_LValueBitCast:
417      case CK_FixedPointCast:
418      case CK_FixedPointToBoolean:
419      case CK_FixedPointToIntegral:
420      case CK_IntegralToFixedPoint: {
421        state =
422            handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred);
423        continue;
424      }
425      case CK_IntegralCast: {
426        // Delegate to SValBuilder to process.
427        SVal V = state->getSVal(Ex, LCtx);
428        V = svalBuilder.evalIntegralCast(state, V, T, ExTy);
429        state = state->BindExpr(CastE, LCtx, V);
430        Bldr.generateNode(CastE, Pred, state);
431        continue;
432      }
433      case CK_DerivedToBase:
434      case CK_UncheckedDerivedToBase: {
435        // For DerivedToBase cast, delegate to the store manager.
436        SVal val = state->getSVal(Ex, LCtx);
437        val = getStoreManager().evalDerivedToBase(val, CastE);
438        state = state->BindExpr(CastE, LCtx, val);
439        Bldr.generateNode(CastE, Pred, state);
440        continue;
441      }
442      // Handle C++ dyn_cast.
443      case CK_Dynamic: {
444        SVal val = state->getSVal(Ex, LCtx);
445
446        // Compute the type of the result.
447        QualType resultType = CastE->getType();
448        if (CastE->isGLValue())
449          resultType = getContext().getPointerType(resultType);
450
451        bool Failed = false;
452
453        // Check if the value being cast evaluates to 0.
454        if (val.isZeroConstant())
455          Failed = true;
456        // Else, evaluate the cast.
457        else
458          val = getStoreManager().attemptDownCast(val, T, Failed);
459
460        if (Failed) {
461          if (T->isReferenceType()) {
462            // A bad_cast exception is thrown if input value is a reference.
463            // Currently, we model this, by generating a sink.
464            Bldr.generateSink(CastE, Pred, state);
465            continue;
466          } else {
467            // If the cast fails on a pointer, bind to 0.
468            state = state->BindExpr(CastE, LCtx, svalBuilder.makeNull());
469          }
470        } else {
471          // If we don't know if the cast succeeded, conjure a new symbol.
472          if (val.isUnknown()) {
473            DefinedOrUnknownSVal NewSym =
474              svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, resultType,
475                                           currBldrCtx->blockCount());
476            state = state->BindExpr(CastE, LCtx, NewSym);
477          } else
478            // Else, bind to the derived region value.
479            state = state->BindExpr(CastE, LCtx, val);
480        }
481        Bldr.generateNode(CastE, Pred, state);
482        continue;
483      }
484      case CK_BaseToDerived: {
485        SVal val = state->getSVal(Ex, LCtx);
486        QualType resultType = CastE->getType();
487        if (CastE->isGLValue())
488          resultType = getContext().getPointerType(resultType);
489
490        bool Failed = false;
491
492        if (!val.isConstant()) {
493          val = getStoreManager().attemptDownCast(val, T, Failed);
494        }
495
496        // Failed to cast or the result is unknown, fall back to conservative.
497        if (Failed || val.isUnknown()) {
498          val =
499            svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, resultType,
500                                         currBldrCtx->blockCount());
501        }
502        state = state->BindExpr(CastE, LCtx, val);
503        Bldr.generateNode(CastE, Pred, state);
504        continue;
505      }
506      case CK_NullToMemberPointer: {
507        SVal V = svalBuilder.getMemberPointer(nullptr);
508        state = state->BindExpr(CastE, LCtx, V);
509        Bldr.generateNode(CastE, Pred, state);
510        continue;
511      }
512      case CK_DerivedToBaseMemberPointer:
513      case CK_BaseToDerivedMemberPointer:
514      case CK_ReinterpretMemberPointer: {
515        SVal V = state->getSVal(Ex, LCtx);
516        if (auto PTMSV = V.getAs<nonloc::PointerToMember>()) {
517          SVal CastedPTMSV = svalBuilder.makePointerToMember(
518              getBasicVals().accumCXXBase(
519                  llvm::make_range<CastExpr::path_const_iterator>(
520                      CastE->path_begin(), CastE->path_end()), *PTMSV));
521          state = state->BindExpr(CastE, LCtx, CastedPTMSV);
522          Bldr.generateNode(CastE, Pred, state);
523          continue;
524        }
525        // Explicitly proceed with default handler for this case cascade.
526        state = handleLVectorSplat(state, LCtx, CastE, Bldr, Pred);
527        continue;
528      }
529      // Various C++ casts that are not handled yet.
530      case CK_ToUnion:
531      case CK_VectorSplat: {
532        state = handleLVectorSplat(state, LCtx, CastE, Bldr, Pred);
533        continue;
534      }
535    }
536  }
537}
538
539void ExprEngine::VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL,
540                                          ExplodedNode *Pred,
541                                          ExplodedNodeSet &Dst) {
542  StmtNodeBuilder B(PredDst, *currBldrCtx);
543
544  ProgramStateRef State = Pred->getState();
545  const LocationContext *LCtx = Pred->getLocationContext();
546
547  const Expr *Init = CL->getInitializer();
548  SVal V = State->getSVal(CL->getInitializer(), LCtx);
549
550  if (isa<CXXConstructExpr>(Init) || isa<CXXStdInitializerListExpr>(Init)) {
551    // No work needed. Just pass the value up to this expression.
552  } else {
553    (Init)", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 553, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(isa<InitListExpr>(Init));
554    Loc CLLoc = State->getLValue(CL, LCtx);
555    State = State->bindLoc(CLLoc, V, LCtx);
556
557    if (CL->isGLValue())
558      V = CLLoc;
559  }
560
561  B.generateNode(CL, Pred, State->BindExpr(CL, LCtx, V));
562}
563
564void ExprEngine::VisitDeclStmt(const DeclStmt *DSExplodedNode *Pred,
565                               ExplodedNodeSet &Dst) {
566  // Assumption: The CFG has one DeclStmt per Decl.
567  const VarDecl *VD = dyn_cast_or_null<VarDecl>(*DS->decl_begin());
568
569  if (!VD) {
570    //TODO:AZ: remove explicit insertion after refactoring is done.
571    Dst.insert(Pred);
572    return;
573  }
574
575  // FIXME: all pre/post visits should eventually be handled by ::Visit().
576  ExplodedNodeSet dstPreVisit;
577  getCheckerManager().runCheckersForPreStmt(dstPreVisitPredDS*this);
578
579  ExplodedNodeSet dstEvaluated;
580  StmtNodeBuilder B(dstPreVisitdstEvaluated, *currBldrCtx);
581  for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
582       I!=E; ++I) {
583    ExplodedNode *N = *I;
584    ProgramStateRef state = N->getState();
585    const LocationContext *LC = N->getLocationContext();
586
587    // Decls without InitExpr are not initialized explicitly.
588    if (const Expr *InitEx = VD->getInit()) {
589
590      // Note in the state that the initialization has occurred.
591      ExplodedNode *UpdatedN = N;
592      SVal InitVal = state->getSVal(InitEx, LC);
593
594      isSingleDecl()", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 594, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(DS->isSingleDecl());
595      if (getObjectUnderConstruction(state, DS, LC)) {
596        state = finishObjectConstruction(state, DS, LC);
597        // We constructed the object directly in the variable.
598        // No need to bind anything.
599        B.generateNode(DS, UpdatedN, state);
600      } else {
601        // Recover some path-sensitivity if a scalar value evaluated to
602        // UnknownVal.
603        if (InitVal.isUnknown()) {
604          QualType Ty = InitEx->getType();
605          if (InitEx->isGLValue()) {
606            Ty = getContext().getPointerType(Ty);
607          }
608
609          InitVal = svalBuilder.conjureSymbolVal(nullptr, InitEx, LC, Ty,
610                                                 currBldrCtx->blockCount());
611        }
612
613
614        B.takeNodes(UpdatedN);
615        ExplodedNodeSet Dst2;
616        evalBind(Dst2, DS, UpdatedN, state->getLValue(VD, LC), InitVal, true);
617        B.addNodes(Dst2);
618      }
619    }
620    else {
621      B.generateNode(DS, N, state);
622    }
623  }
624
625  getCheckerManager().runCheckersForPostStmt(Dst, B.getResults(), DS, *this);
626}
627
628void ExprEngine::VisitLogicalExpr(const BinaryOperatorBExplodedNode *Pred,
629                                  ExplodedNodeSet &Dst) {
630  getOpcode() == BO_LAnd || B->getOpcode() == BO_LOr", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 631, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(B->getOpcode() == BO_LAnd ||
631getOpcode() == BO_LAnd || B->getOpcode() == BO_LOr", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 631, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">         B->getOpcode() == BO_LOr);
632
633  StmtNodeBuilder Bldr(PredDst, *currBldrCtx);
634  ProgramStateRef state = Pred->getState();
635
636  if (B->getType()->isVectorType()) {
637    // FIXME: We do not model vector arithmetic yet. When adding support for
638    // that, note that the CFG-based reasoning below does not apply, because
639    // logical operators on vectors are not short-circuit. Currently they are
640    // modeled as short-circuit in Clang CFG but this is incorrect.
641    // Do not set the value for the expression. It'd be UnknownVal by default.
642    Bldr.generateNode(B, Pred, state);
643    return;
644  }
645
646  ExplodedNode *N = Pred;
647  while (!N->getLocation().getAs<BlockEntrance>()) {
648    ProgramPoint P = N->getLocation();
649    ()|| P.getAs()", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 649, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(P.getAs<PreStmt>()|| P.getAs<PreStmtPurgeDeadSymbols>());
650    (voidP;
651    pred_size() == 1", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 651, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(N->pred_size() == 1);
652    N = *N->pred_begin();
653  }
654  pred_size() == 1", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 654, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(N->pred_size() == 1);
655  N = *N->pred_begin();
656  BlockEdge BE = N->getLocation().castAs<BlockEdge>();
657  SVal X;
658
659  // Determine the value of the expression by introspecting how we
660  // got this location in the CFG.  This requires looking at the previous
661  // block we were in and what kind of control-flow transfer was involved.
662  const CFGBlock *SrcBlock = BE.getSrc();
663  // The only terminator (if there is one) that makes sense is a logical op.
664  CFGTerminator T = SrcBlock->getTerminator();
665  if (const BinaryOperator *Term = cast_or_null<BinaryOperator>(T.getStmt())) {
666    (voidTerm;
667    isLogicalOp()", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 667, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(Term->isLogicalOp());
668    succ_size() == 2", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 668, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(SrcBlock->succ_size() == 2);
669    // Did we take the true or false branch?
670    unsigned constant = (*SrcBlock->succ_begin() == BE.getDst()) ? 1 : 0;
671    X = svalBuilder.makeIntVal(constantB->getType());
672  }
673  else {
674    // If there is no terminator, by construction the last statement
675    // in SrcBlock is the value of the enclosing expression.
676    // However, we still need to constrain that value to be 0 or 1.
677    empty()", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 677, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(!SrcBlock->empty());
678    CFGStmt Elem = SrcBlock->rbegin()->castAs<CFGStmt>();
679    const Expr *RHS = cast<Expr>(Elem.getStmt());
680    SVal RHSVal = N->getState()->getSVal(RHS, Pred->getLocationContext());
681
682    if (RHSVal.isUndef()) {
683      X = RHSVal;
684    } else {
685      // We evaluate "RHSVal != 0" expression which result in 0 if the value is
686      // known to be false, 1 if the value is known to be true and a new symbol
687      // when the assumption is unknown.
688      nonloc::ConcreteInt Zero(getBasicVals().getValue(0B->getType()));
689      X = evalBinOp(N->getState(), BO_NE,
690                    svalBuilder.evalCast(RHSValB->getType(), RHS->getType()),
691                    ZeroB->getType());
692    }
693  }
694  Bldr.generateNode(B, Pred, state->BindExpr(B, Pred->getLocationContext(), X));
695}
696
697void ExprEngine::VisitInitListExpr(const InitListExpr *IE,
698                                   ExplodedNode *Pred,
699                                   ExplodedNodeSet &Dst) {
700  StmtNodeBuilder B(PredDst, *currBldrCtx);
701
702  ProgramStateRef state = Pred->getState();
703  const LocationContext *LCtx = Pred->getLocationContext();
704  QualType T = getContext().getCanonicalType(IE->getType());
705  unsigned NumInitElements = IE->getNumInits();
706
707  if (!IE->isGLValue() && !IE->isTransparent() &&
708      (T->isArrayType() || T->isRecordType() || T->isVectorType() ||
709       T->isAnyComplexType())) {
710    llvm::ImmutableList<SVal> vals = getBasicVals().getEmptySValList();
711
712    // Handle base case where the initializer has no elements.
713    // e.g: static int* myArray[] = {};
714    if (NumInitElements == 0) {
715      SVal V = svalBuilder.makeCompoundVal(T, vals);
716      B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));
717      return;
718    }
719
720    for (InitListExpr::const_reverse_iterator it = IE->rbegin(),
721         ei = IE->rend(); it != ei; ++it) {
722      SVal V = state->getSVal(cast<Expr>(*it), LCtx);
723      vals = getBasicVals().prependSVal(V, vals);
724    }
725
726    B.generateNode(IE, Pred,
727                   state->BindExpr(IE, LCtx,
728                                   svalBuilder.makeCompoundVal(T, vals)));
729    return;
730  }
731
732  // Handle scalars: int{5} and int{} and GLvalues.
733  // Note, if the InitListExpr is a GLvalue, it means that there is an address
734  // representing it, so it must have a single init element.
735  assert(NumInitElements <= 1);
736
737  SVal V;
738  if (NumInitElements == 0)
739    V = getSValBuilder().makeZeroVal(T);
740  else
741    V = state->getSVal(IE->getInit(0), LCtx);
742
743  B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));
744}
745
746void ExprEngine::VisitGuardedExpr(const Expr *Ex,
747                                  const Expr *L,
748                                  const Expr *R,
749                                  ExplodedNode *Pred,
750                                  ExplodedNodeSet &Dst) {
751  assert(L && R);
752
753  StmtNodeBuilder B(PredDst, *currBldrCtx);
754  ProgramStateRef state = Pred->getState();
755  const LocationContext *LCtx = Pred->getLocationContext();
756  const CFGBlock *SrcBlock = nullptr;
757
758  // Find the predecessor block.
759  ProgramStateRef SrcState = state;
760  for (const ExplodedNode *N = Pred ; N ; N = *N->pred_begin()) {
761    ProgramPoint PP = N->getLocation();
762    if (PP.getAs<PreStmtPurgeDeadSymbols>() || PP.getAs<BlockEntrance>()) {
763      // If the state N has multiple predecessors P, it means that successors
764      // of P are all equivalent.
765      // In turn, that means that all nodes at P are equivalent in terms
766      // of observable behavior at N, and we can follow any of them.
767      // FIXME: a more robust solution which does not walk up the tree.
768      continue;
769    }
770    SrcBlock = PP.castAs<BlockEdge>().getSrc();
771    SrcState = N->getState();
772    break;
773  }
774
775   (0) . __assert_fail ("SrcBlock && \"missing function entry\"", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 775, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(SrcBlock && "missing function entry");
776
777  // Find the last expression in the predecessor block.  That is the
778  // expression that is used for the value of the ternary expression.
779  bool hasValue = false;
780  SVal V;
781
782  for (CFGElement CE : llvm::reverse(*SrcBlock)) {
783    if (Optional<CFGStmt> CS = CE.getAs<CFGStmt>()) {
784      const Expr *ValEx = cast<Expr>(CS->getStmt());
785      ValEx = ValEx->IgnoreParens();
786
787      // For GNU extension '?:' operator, the left hand side will be an
788      // OpaqueValueExpr, so get the underlying expression.
789      if (const OpaqueValueExpr *OpaqueEx = dyn_cast<OpaqueValueExpr>(L))
790        L = OpaqueEx->getSourceExpr();
791
792      // If the last expression in the predecessor block matches true or false
793      // subexpression, get its the value.
794      if (ValEx == L->IgnoreParens() || ValEx == R->IgnoreParens()) {
795        hasValue = true;
796        V = SrcState->getSVal(ValEx, LCtx);
797      }
798      break;
799    }
800  }
801
802  if (!hasValue)
803    V = svalBuilder.conjureSymbolVal(nullptrExLCtx,
804                                     currBldrCtx->blockCount());
805
806  // Generate a new node with the binding from the appropriate path.
807  B.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V, true));
808}
809
810void ExprEngine::
811VisitOffsetOfExpr(const OffsetOfExpr *OOE,
812                  ExplodedNode *PredExplodedNodeSet &Dst) {
813  StmtNodeBuilder B(PredDst, *currBldrCtx);
814  Expr::EvalResult Result;
815  if (OOE->EvaluateAsInt(ResultgetContext())) {
816    APSInt IV = Result.Val.getInt();
817    getType())", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 817, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(IV.getBitWidth() == getContext().getTypeSize(OOE->getType()));
818    getType()->isBuiltinType()", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 818, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(OOE->getType()->isBuiltinType());
819    getType()->getAs()->isInteger()", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 819, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(OOE->getType()->getAs<BuiltinType>()->isInteger());
820    getType()->isSignedIntegerType()", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 820, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(IV.isSigned() == OOE->getType()->isSignedIntegerType());
821    SVal X = svalBuilder.makeIntVal(IV);
822    B.generateNode(OOE, Pred,
823                   Pred->getState()->BindExpr(OOE, Pred->getLocationContext(),
824                                              X));
825  }
826  // FIXME: Handle the case where __builtin_offsetof is not a constant.
827}
828
829
830void ExprEngine::
831VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex,
832                              ExplodedNode *Pred,
833                              ExplodedNodeSet &Dst) {
834  // FIXME: Prechecks eventually go in ::Visit().
835  ExplodedNodeSet CheckedSet;
836  getCheckerManager().runCheckersForPreStmt(CheckedSetPredEx*this);
837
838  ExplodedNodeSet EvalSet;
839  StmtNodeBuilder Bldr(CheckedSetEvalSet, *currBldrCtx);
840
841  QualType T = Ex->getTypeOfArgument();
842
843  for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
844       I != E; ++I) {
845    if (Ex->getKind() == UETT_SizeOf) {
846      if (!T->isIncompleteType() && !T->isConstantSizeType()) {
847         (0) . __assert_fail ("T->isVariableArrayType() && \"Unknown non-constant-sized type.\"", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 847, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(T->isVariableArrayType() && "Unknown non-constant-sized type.");
848
849        // FIXME: Add support for VLA type arguments and VLA expressions.
850        // When that happens, we should probably refactor VLASizeChecker's code.
851        continue;
852      } else if (T->getAs<ObjCObjectType>()) {
853        // Some code tries to take the sizeof an ObjCObjectType, relying that
854        // the compiler has laid out its representation.  Just report Unknown
855        // for these.
856        continue;
857      }
858    }
859
860    APSInt Value = Ex->EvaluateKnownConstInt(getContext());
861    CharUnits amt = CharUnits::fromQuantity(Value.getZExtValue());
862
863    ProgramStateRef state = (*I)->getState();
864    state = state->BindExpr(Ex, (*I)->getLocationContext(),
865                            svalBuilder.makeIntVal(amt.getQuantity(),
866                                                   Ex->getType()));
867    Bldr.generateNode(Ex, *I, state);
868  }
869
870  getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, Ex, *this);
871}
872
873void ExprEngine::handleUOExtension(ExplodedNodeSet::iterator I,
874                                   const UnaryOperator *U,
875                                   StmtNodeBuilder &Bldr) {
876  // FIXME: We can probably just have some magic in Environment::getSVal()
877  // that propagates values, instead of creating a new node here.
878  //
879  // Unary "+" is a no-op, similar to a parentheses.  We still have places
880  // where it may be a block-level expression, so we need to
881  // generate an extra node that just propagates the value of the
882  // subexpression.
883  const Expr *Ex = U->getSubExpr()->IgnoreParens();
884  ProgramStateRef state = (*I)->getState();
885  const LocationContext *LCtx = (*I)->getLocationContext();
886  Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
887                                           state->getSVal(Ex, LCtx)));
888}
889
890void ExprEngine::VisitUnaryOperator(const UnaryOperatorUExplodedNode *Pred,
891                                    ExplodedNodeSet &Dst) {
892  // FIXME: Prechecks eventually go in ::Visit().
893  ExplodedNodeSet CheckedSet;
894  getCheckerManager().runCheckersForPreStmt(CheckedSetPredU*this);
895
896  ExplodedNodeSet EvalSet;
897  StmtNodeBuilder Bldr(CheckedSetEvalSet, *currBldrCtx);
898
899  for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
900       I != E; ++I) {
901    switch (U->getOpcode()) {
902    default: {
903      Bldr.takeNodes(*I);
904      ExplodedNodeSet Tmp;
905      VisitIncrementDecrementOperator(U, *I, Tmp);
906      Bldr.addNodes(Tmp);
907      break;
908    }
909    case UO_Real: {
910      const Expr *Ex = U->getSubExpr()->IgnoreParens();
911
912      // FIXME: We don't have complex SValues yet.
913      if (Ex->getType()->isAnyComplexType()) {
914        // Just report "Unknown."
915        break;
916      }
917
918      // For all other types, UO_Real is an identity operation.
919      getType() == Ex->getType()", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 919, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert (U->getType() == Ex->getType());
920      ProgramStateRef state = (*I)->getState();
921      const LocationContext *LCtx = (*I)->getLocationContext();
922      Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
923                                               state->getSVal(Ex, LCtx)));
924      break;
925    }
926
927    case UO_Imag: {
928      const Expr *Ex = U->getSubExpr()->IgnoreParens();
929      // FIXME: We don't have complex SValues yet.
930      if (Ex->getType()->isAnyComplexType()) {
931        // Just report "Unknown."
932        break;
933      }
934      // For all other types, UO_Imag returns 0.
935      ProgramStateRef state = (*I)->getState();
936      const LocationContext *LCtx = (*I)->getLocationContext();
937      SVal X = svalBuilder.makeZeroVal(Ex->getType());
938      Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, X));
939      break;
940    }
941
942    case UO_AddrOf: {
943      // Process pointer-to-member address operation.
944      const Expr *Ex = U->getSubExpr()->IgnoreParens();
945      if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Ex)) {
946        const ValueDecl *VD = DRE->getDecl();
947
948        if (isa<CXXMethodDecl>(VD) || isa<FieldDecl>(VD)) {
949          ProgramStateRef State = (*I)->getState();
950          const LocationContext *LCtx = (*I)->getLocationContext();
951          SVal SV = svalBuilder.getMemberPointer(cast<DeclaratorDecl>(VD));
952          Bldr.generateNode(U, *I, State->BindExpr(U, LCtx, SV));
953          break;
954        }
955      }
956      // Explicitly proceed with default handler for this case cascade.
957      handleUOExtension(I, U, Bldr);
958      break;
959    }
960    case UO_Plus:
961      isGLValue()", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 961, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(!U->isGLValue());
962      LLVM_FALLTHROUGH;
963    case UO_Deref:
964    case UO_Extension: {
965      handleUOExtension(I, U, Bldr);
966      break;
967    }
968
969    case UO_LNot:
970    case UO_Minus:
971    case UO_Not: {
972      isGLValue()", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 972, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert (!U->isGLValue());
973      const Expr *Ex = U->getSubExpr()->IgnoreParens();
974      ProgramStateRef state = (*I)->getState();
975      const LocationContext *LCtx = (*I)->getLocationContext();
976
977      // Get the value of the subexpression.
978      SVal V = state->getSVal(Ex, LCtx);
979
980      if (V.isUnknownOrUndef()) {
981        Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, V));
982        break;
983      }
984
985      switch (U->getOpcode()) {
986        default:
987          llvm_unreachable("Invalid Opcode.");
988        case UO_Not:
989          // FIXME: Do we need to handle promotions?
990          state = state->BindExpr(U, LCtx, evalComplement(V.castAs<NonLoc>()));
991          break;
992        case UO_Minus:
993          // FIXME: Do we need to handle promotions?
994          state = state->BindExpr(U, LCtx, evalMinus(V.castAs<NonLoc>()));
995          break;
996        case UO_LNot:
997          // C99 6.5.3.3: "The expression !E is equivalent to (0==E)."
998          //
999          //  Note: technically we do "E == 0", but this is the same in the
1000          //    transfer functions as "0 == E".
1001          SVal Result;
1002          if (Optional<Loc> LV = V.getAs<Loc>()) {
1003            Loc X = svalBuilder.makeNullWithType(Ex->getType());
1004            Result = evalBinOp(state, BO_EQ, *LV, X, U->getType());
1005          } else if (Ex->getType()->isFloatingType()) {
1006            // FIXME: handle floating point types.
1007            Result = UnknownVal();
1008          } else {
1009            nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
1010            Result = evalBinOp(state, BO_EQ, V.castAs<NonLoc>(), X,
1011                               U->getType());
1012          }
1013
1014          state = state->BindExpr(U, LCtx, Result);
1015          break;
1016      }
1017      Bldr.generateNode(U, *I, state);
1018      break;
1019    }
1020    }
1021  }
1022
1023  getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, U, *this);
1024}
1025
1026void ExprEngine::VisitIncrementDecrementOperator(const UnaryOperatorU,
1027                                                 ExplodedNode *Pred,
1028                                                 ExplodedNodeSet &Dst) {
1029  // Handle ++ and -- (both pre- and post-increment).
1030  isIncrementDecrementOp()", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 1030, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert (U->isIncrementDecrementOp());
1031  const Expr *Ex = U->getSubExpr()->IgnoreParens();
1032
1033  const LocationContext *LCtx = Pred->getLocationContext();
1034  ProgramStateRef state = Pred->getState();
1035  SVal loc = state->getSVal(Ex, LCtx);
1036
1037  // Perform a load.
1038  ExplodedNodeSet Tmp;
1039  evalLoad(Tmp, U, Ex, Pred, state, loc);
1040
1041  ExplodedNodeSet Dst2;
1042  StmtNodeBuilder Bldr(TmpDst2, *currBldrCtx);
1043  for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end();I!=E;++I) {
1044
1045    state = (*I)->getState();
1046    getLocationContext()", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp", 1046, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(LCtx == (*I)->getLocationContext());
1047    SVal V2_untested = state->getSVal(Ex, LCtx);
1048
1049    // Propagate unknown and undefined values.
1050    if (V2_untested.isUnknownOrUndef()) {
1051      state = state->BindExpr(U, LCtx, V2_untested);
1052
1053      // Perform the store, so that the uninitialized value detection happens.
1054      Bldr.takeNodes(*I);
1055      ExplodedNodeSet Dst3;
1056      evalStore(Dst3, U, Ex, *I, state, loc, V2_untested);
1057      Bldr.addNodes(Dst3);
1058
1059      continue;
1060    }
1061    DefinedSVal V2 = V2_untested.castAs<DefinedSVal>();
1062
1063    // Handle all other values.
1064    BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add : BO_Sub;
1065
1066    // If the UnaryOperator has non-location type, use its type to create the
1067    // constant value. If the UnaryOperator has location type, create the
1068    // constant with int type and pointer width.
1069    SVal RHS;
1070    SVal Result;
1071
1072    if (U->getType()->isAnyPointerType())
1073      RHS = svalBuilder.makeArrayIndex(1);
1074    else if (U->getType()->isIntegralOrEnumerationType())
1075      RHS = svalBuilder.makeIntVal(1, U->getType());
1076    else
1077      RHS = UnknownVal();
1078
1079    // The use of an operand of type bool with the ++ operators is deprecated
1080    // but valid until C++17. And if the operand of the ++ operator is of type
1081    // bool, it is set to true until C++17. Note that for '_Bool', it is also
1082    // set to true when it encounters ++ operator.
1083    if (U->getType()->isBooleanType() && U->isIncrementOp())
1084      Result = svalBuilder.makeTruthVal(true, U->getType());
1085    else
1086      Result = evalBinOp(state, Op, V2, RHS, U->getType());
1087
1088    // Conjure a new symbol if necessary to recover precision.
1089    if (Result.isUnknown()){
1090      DefinedOrUnknownSVal SymVal =
1091        svalBuilder.conjureSymbolVal(nullptr, U, LCtx,
1092                                     currBldrCtx->blockCount());
1093      Result = SymVal;
1094
1095      // If the value is a location, ++/-- should always preserve
1096      // non-nullness.  Check if the original value was non-null, and if so
1097      // propagate that constraint.
1098      if (Loc::isLocType(U->getType())) {
1099        DefinedOrUnknownSVal Constraint =
1100        svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(U->getType()));
1101
1102        if (!state->assume(Constraint, true)) {
1103          // It isn't feasible for the original value to be null.
1104          // Propagate this constraint.
1105          Constraint = svalBuilder.evalEQ(state, SymVal,
1106                                       svalBuilder.makeZeroVal(U->getType()));
1107
1108          state = state->assume(Constraint, false);
1109          assert(state);
1110        }
1111      }
1112    }
1113
1114    // Since the lvalue-to-rvalue conversion is explicit in the AST,
1115    // we bind an l-value if the operator is prefix and an lvalue (in C++).
1116    if (U->isGLValue())
1117      state = state->BindExpr(U, LCtx, loc);
1118    else
1119      state = state->BindExpr(U, LCtx, U->isPostfix() ? V2 : Result);
1120
1121    // Perform the store.
1122    Bldr.takeNodes(*I);
1123    ExplodedNodeSet Dst3;
1124    evalStore(Dst3, U, Ex, *I, state, loc, Result);
1125    Bldr.addNodes(Dst3);
1126  }
1127  Dst.insert(Dst2);
1128}
1129
clang::ento::ExprEngine::VisitBinaryOperator
clang::ento::ExprEngine::VisitBlockExpr
clang::ento::ExprEngine::handleLValueBitCast
clang::ento::ExprEngine::handleLVectorSplat
clang::ento::ExprEngine::VisitCast
clang::ento::ExprEngine::VisitCompoundLiteralExpr
clang::ento::ExprEngine::VisitDeclStmt
clang::ento::ExprEngine::VisitLogicalExpr
clang::ento::ExprEngine::VisitInitListExpr
clang::ento::ExprEngine::VisitGuardedExpr
clang::ento::ExprEngine::VisitOffsetOfExpr
clang::ento::ExprEngine::VisitUnaryExprOrTypeTraitExpr
clang::ento::ExprEngine::handleUOExtension
clang::ento::ExprEngine::VisitUnaryOperator
clang::ento::ExprEngine::VisitIncrementDecrementOperator