Coverage Report

Created: 2023-09-30 09:22

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- ExprEngineCXX.cpp - ExprEngine support for C++ -----------*- 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 the C++ expression evaluation engine.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "clang/AST/DeclCXX.h"
14
#include "clang/AST/ParentMap.h"
15
#include "clang/AST/StmtCXX.h"
16
#include "clang/Analysis/ConstructionContext.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
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
22
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
23
#include "llvm/ADT/STLExtras.h"
24
#include "llvm/ADT/Sequence.h"
25
#include <optional>
26
27
using namespace clang;
28
using namespace ento;
29
30
void ExprEngine::CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME,
31
                                          ExplodedNode *Pred,
32
8.75k
                                          ExplodedNodeSet &Dst) {
33
8.75k
  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
34
8.75k
  const Expr *tempExpr = ME->getSubExpr()->IgnoreParens();
35
8.75k
  ProgramStateRef state = Pred->getState();
36
8.75k
  const LocationContext *LCtx = Pred->getLocationContext();
37
38
8.75k
  state = createTemporaryRegionIfNeeded(state, LCtx, tempExpr, ME);
39
8.75k
  Bldr.generateNode(ME, Pred, state);
40
8.75k
}
41
42
// FIXME: This is the sort of code that should eventually live in a Core
43
// checker rather than as a special case in ExprEngine.
44
void ExprEngine::performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
45
12.6k
                                    const CallEvent &Call) {
46
12.6k
  SVal ThisVal;
47
12.6k
  bool AlwaysReturnsLValue;
48
12.6k
  const CXXRecordDecl *ThisRD = nullptr;
49
12.6k
  if (const CXXConstructorCall *Ctor = dyn_cast<CXXConstructorCall>(&Call)) {
50
12.5k
    assert(Ctor->getDecl()->isTrivial());
51
12.5k
    assert(Ctor->getDecl()->isCopyOrMoveConstructor());
52
12.5k
    ThisVal = Ctor->getCXXThisVal();
53
12.5k
    ThisRD = Ctor->getDecl()->getParent();
54
12.5k
    AlwaysReturnsLValue = false;
55
12.5k
  } else {
56
122
    assert(cast<CXXMethodDecl>(Call.getDecl())->isTrivial());
57
122
    assert(cast<CXXMethodDecl>(Call.getDecl())->getOverloadedOperator() ==
58
122
           OO_Equal);
59
122
    ThisVal = cast<CXXInstanceCall>(Call).getCXXThisVal();
60
122
    ThisRD = cast<CXXMethodDecl>(Call.getDecl())->getParent();
61
122
    AlwaysReturnsLValue = true;
62
122
  }
63
64
12.6k
  const LocationContext *LCtx = Pred->getLocationContext();
65
12.6k
  const Expr *CallExpr = Call.getOriginExpr();
66
67
12.6k
  ExplodedNodeSet Dst;
68
12.6k
  Bldr.takeNodes(Pred);
69
70
12.6k
  assert(ThisRD);
71
12.6k
  if (!ThisRD->isEmpty()) {
72
    // Load the source value only for non-empty classes.
73
    // Otherwise it'd retrieve an UnknownVal
74
    // and bind it and RegionStore would think that the actual value
75
    // in this region at this offset is unknown.
76
10.9k
    SVal V = Call.getArgSVal(0);
77
78
    // If the value being copied is not unknown, load from its location to get
79
    // an aggregate rvalue.
80
10.9k
    if (std::optional<Loc> L = V.getAs<Loc>())
81
10.9k
      V = Pred->getState()->getSVal(*L);
82
9
    else
83
9
      assert(V.isUnknownOrUndef());
84
10.9k
    evalBind(Dst, CallExpr, Pred, ThisVal, V, true);
85
10.9k
  } else {
86
1.70k
    Dst.Add(Pred);
87
1.70k
  }
88
89
12.6k
  PostStmt PS(CallExpr, LCtx);
90
12.6k
  for (ExplodedNode *N : Dst) {
91
12.6k
    ProgramStateRef State = N->getState();
92
12.6k
    if (AlwaysReturnsLValue)
93
122
      State = State->BindExpr(CallExpr, LCtx, ThisVal);
94
12.5k
    else
95
12.5k
      State = bindReturnValue(Call, LCtx, State);
96
12.6k
    Bldr.generateNode(PS, State, N);
97
12.6k
  }
98
12.6k
}
99
100
SVal ExprEngine::makeElementRegion(ProgramStateRef State, SVal LValue,
101
11.4k
                                   QualType &Ty, bool &IsArray, unsigned Idx) {
102
11.4k
  SValBuilder &SVB = State->getStateManager().getSValBuilder();
103
11.4k
  ASTContext &Ctx = SVB.getContext();
104
105
11.4k
  if (const ArrayType *AT = Ctx.getAsArrayType(Ty)) {
106
1.28k
    while (AT) {
107
699
      Ty = AT->getElementType();
108
699
      AT = dyn_cast<ArrayType>(AT->getElementType());
109
699
    }
110
586
    LValue = State->getLValue(Ty, SVB.makeArrayIndex(Idx), LValue);
111
586
    IsArray = true;
112
586
  }
113
114
11.4k
  return LValue;
115
11.4k
}
116
117
// In case when the prvalue is returned from the function (kind is one of
118
// SimpleReturnedValueKind, CXX17ElidedCopyReturnedValueKind), then
119
// it's materialization happens in context of the caller.
120
// We pass BldrCtx explicitly, as currBldrCtx always refers to callee's context.
121
SVal ExprEngine::computeObjectUnderConstruction(
122
    const Expr *E, ProgramStateRef State, const NodeBuilderContext *BldrCtx,
123
    const LocationContext *LCtx, const ConstructionContext *CC,
124
33.3k
    EvalCallOptions &CallOpts, unsigned Idx) {
125
126
33.3k
  SValBuilder &SVB = getSValBuilder();
127
33.3k
  MemRegionManager &MRMgr = SVB.getRegionManager();
128
33.3k
  ASTContext &ACtx = SVB.getContext();
129
130
  // Compute the target region by exploring the construction context.
131
33.3k
  if (CC) {
132
33.0k
    switch (CC->getKind()) {
133
44
    case ConstructionContext::CXX17ElidedCopyVariableKind:
134
7.77k
    case ConstructionContext::SimpleVariableKind: {
135
7.77k
      const auto *DSCC = cast<VariableConstructionContext>(CC);
136
7.77k
      const auto *DS = DSCC->getDeclStmt();
137
7.77k
      const auto *Var = cast<VarDecl>(DS->getSingleDecl());
138
7.77k
      QualType Ty = Var->getType();
139
7.77k
      return makeElementRegion(State, State->getLValue(Var, LCtx), Ty,
140
7.77k
                               CallOpts.IsArrayCtorOrDtor, Idx);
141
44
    }
142
4
    case ConstructionContext::CXX17ElidedCopyConstructorInitializerKind:
143
2.83k
    case ConstructionContext::SimpleConstructorInitializerKind: {
144
2.83k
      const auto *ICC = cast<ConstructorInitializerConstructionContext>(CC);
145
2.83k
      const auto *Init = ICC->getCXXCtorInitializer();
146
2.83k
      const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
147
2.83k
      Loc ThisPtr = SVB.getCXXThis(CurCtor, LCtx->getStackFrame());
148
2.83k
      SVal ThisVal = State->getSVal(ThisPtr);
149
2.83k
      if (Init->isBaseInitializer()) {
150
2
        const auto *ThisReg = cast<SubRegion>(ThisVal.getAsRegion());
151
2
        const CXXRecordDecl *BaseClass =
152
2
          Init->getBaseClass()->getAsCXXRecordDecl();
153
2
        const auto *BaseReg =
154
2
          MRMgr.getCXXBaseObjectRegion(BaseClass, ThisReg,
155
2
                                       Init->isBaseVirtual());
156
2
        return SVB.makeLoc(BaseReg);
157
2
      }
158
2.83k
      if (Init->isDelegatingInitializer())
159
1
        return ThisVal;
160
161
2.82k
      const ValueDecl *Field;
162
2.82k
      SVal FieldVal;
163
2.82k
      if (Init->isIndirectMemberInitializer()) {
164
0
        Field = Init->getIndirectMember();
165
0
        FieldVal = State->getLValue(Init->getIndirectMember(), ThisVal);
166
2.82k
      } else {
167
2.82k
        Field = Init->getMember();
168
2.82k
        FieldVal = State->getLValue(Init->getMember(), ThisVal);
169
2.82k
      }
170
171
2.82k
      QualType Ty = Field->getType();
172
2.82k
      return makeElementRegion(State, FieldVal, Ty, CallOpts.IsArrayCtorOrDtor,
173
2.82k
                               Idx);
174
2.83k
    }
175
595
    case ConstructionContext::NewAllocatedObjectKind: {
176
595
      if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
177
592
        const auto *NECC = cast<NewAllocatedObjectConstructionContext>(CC);
178
592
        const auto *NE = NECC->getCXXNewExpr();
179
592
        SVal V = *getObjectUnderConstruction(State, NE, LCtx);
180
592
        if (const SubRegion *MR =
181
592
                dyn_cast_or_null<SubRegion>(V.getAsRegion())) {
182
580
          if (NE->isArray()) {
183
134
            CallOpts.IsArrayCtorOrDtor = true;
184
185
134
            auto Ty = NE->getType()->getPointeeType();
186
144
            while (const auto *AT = getContext().getAsArrayType(Ty))
187
10
              Ty = AT->getElementType();
188
189
134
            auto R = MRMgr.getElementRegion(Ty, svalBuilder.makeArrayIndex(Idx),
190
134
                                            MR, SVB.getContext());
191
192
134
            return loc::MemRegionVal(R);
193
134
          }
194
446
          return  V;
195
580
        }
196
        // TODO: Detect when the allocator returns a null pointer.
197
        // Constructor shall not be called in this case.
198
592
      }
199
15
      break;
200
595
    }
201
2.49k
    case ConstructionContext::SimpleReturnedValueKind:
202
2.54k
    case ConstructionContext::CXX17ElidedCopyReturnedValueKind: {
203
      // The temporary is to be managed by the parent stack frame.
204
      // So build it in the parent stack frame if we're not in the
205
      // top frame of the analysis.
206
2.54k
      const StackFrameContext *SFC = LCtx->getStackFrame();
207
2.54k
      if (const LocationContext *CallerLCtx = SFC->getParent()) {
208
2.48k
        auto RTC = (*SFC->getCallSiteBlock())[SFC->getIndex()]
209
2.48k
                       .getAs<CFGCXXRecordTypedCall>();
210
2.48k
        if (!RTC) {
211
          // We were unable to find the correct construction context for the
212
          // call in the parent stack frame. This is equivalent to not being
213
          // able to find construction context at all.
214
326
          break;
215
326
        }
216
2.16k
        if (isa<BlockInvocationContext>(CallerLCtx)) {
217
          // Unwrap block invocation contexts. They're mostly part of
218
          // the current stack frame.
219
1
          CallerLCtx = CallerLCtx->getParent();
220
1
          assert(!isa<BlockInvocationContext>(CallerLCtx));
221
1
        }
222
223
2.16k
        NodeBuilderContext CallerBldrCtx(getCoreEngine(),
224
2.16k
                                         SFC->getCallSiteBlock(), CallerLCtx);
225
2.16k
        return computeObjectUnderConstruction(
226
2.16k
            cast<Expr>(SFC->getCallSite()), State, &CallerBldrCtx, CallerLCtx,
227
2.16k
            RTC->getConstructionContext(), CallOpts);
228
2.16k
      } else {
229
        // We are on the top frame of the analysis. We do not know where is the
230
        // object returned to. Conjure a symbolic region for the return value.
231
        // TODO: We probably need a new MemRegion kind to represent the storage
232
        // of that SymbolicRegion, so that we cound produce a fancy symbol
233
        // instead of an anonymous conjured symbol.
234
        // TODO: Do we need to track the region to avoid having it dead
235
        // too early? It does die too early, at least in C++17, but because
236
        // putting anything into a SymbolicRegion causes an immediate escape,
237
        // it doesn't cause any leak false positives.
238
56
        const auto *RCC = cast<ReturnedValueConstructionContext>(CC);
239
        // Make sure that this doesn't coincide with any other symbol
240
        // conjured for the returned expression.
241
56
        static const int TopLevelSymRegionTag = 0;
242
56
        const Expr *RetE = RCC->getReturnStmt()->getRetValue();
243
56
        assert(RetE && "Void returns should not have a construction context");
244
56
        QualType ReturnTy = RetE->getType();
245
56
        QualType RegionTy = ACtx.getPointerType(ReturnTy);
246
56
        return SVB.conjureSymbolVal(&TopLevelSymRegionTag, RetE, SFC, RegionTy,
247
56
                                    currBldrCtx->blockCount());
248
56
      }
249
0
      llvm_unreachable("Unhandled return value construction context!");
250
0
    }
251
6.21k
    case ConstructionContext::ElidedTemporaryObjectKind: {
252
6.21k
      assert(AMgr.getAnalyzerOptions().ShouldElideConstructors);
253
6.21k
      const auto *TCC = cast<ElidedTemporaryObjectConstructionContext>(CC);
254
255
      // Support pre-C++17 copy elision. We'll have the elidable copy
256
      // constructor in the AST and in the CFG, but we'll skip it
257
      // and construct directly into the final object. This call
258
      // also sets the CallOpts flags for us.
259
      // If the elided copy/move constructor is not supported, there's still
260
      // benefit in trying to model the non-elided constructor.
261
      // Stash our state before trying to elide, as it'll get overwritten.
262
6.21k
      ProgramStateRef PreElideState = State;
263
6.21k
      EvalCallOptions PreElideCallOpts = CallOpts;
264
265
6.21k
      SVal V = computeObjectUnderConstruction(
266
6.21k
          TCC->getConstructorAfterElision(), State, BldrCtx, LCtx,
267
6.21k
          TCC->getConstructionContextAfterElision(), CallOpts);
268
269
      // FIXME: This definition of "copy elision has not failed" is unreliable.
270
      // It doesn't indicate that the constructor will actually be inlined
271
      // later; this is still up to evalCall() to decide.
272
6.21k
      if (!CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion)
273
6.08k
        return V;
274
275
      // Copy elision failed. Revert the changes and proceed as if we have
276
      // a simple temporary.
277
130
      CallOpts = PreElideCallOpts;
278
130
      CallOpts.IsElidableCtorThatHasNotBeenElided = true;
279
130
      [[fallthrough]];
280
130
    }
281
2.13k
    case ConstructionContext::SimpleTemporaryObjectKind: {
282
2.13k
      const auto *TCC = cast<TemporaryObjectConstructionContext>(CC);
283
2.13k
      const MaterializeTemporaryExpr *MTE = TCC->getMaterializedTemporaryExpr();
284
285
2.13k
      CallOpts.IsTemporaryCtorOrDtor = true;
286
2.13k
      if (MTE) {
287
2.01k
        if (const ValueDecl *VD = MTE->getExtendingDecl()) {
288
197
          StorageDuration SD = MTE->getStorageDuration();
289
197
          assert(SD != SD_FullExpression);
290
197
          if (!VD->getType()->isReferenceType()) {
291
            // We're lifetime-extended by a surrounding aggregate.
292
            // Automatic destructors aren't quite working in this case
293
            // on the CFG side. We should warn the caller about that.
294
            // FIXME: Is there a better way to retrieve this information from
295
            // the MaterializeTemporaryExpr?
296
24
            CallOpts.IsTemporaryLifetimeExtendedViaAggregate = true;
297
24
          }
298
299
197
          if (SD == SD_Static || 
SD == SD_Thread189
)
300
14
            return loc::MemRegionVal(
301
14
                MRMgr.getCXXStaticLifetimeExtendedObjectRegion(E, VD));
302
303
183
          return loc::MemRegionVal(
304
183
              MRMgr.getCXXLifetimeExtendedObjectRegion(E, VD, LCtx));
305
197
        }
306
1.81k
        assert(MTE->getStorageDuration() == SD_FullExpression);
307
1.81k
      }
308
309
1.93k
      return loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx));
310
2.13k
    }
311
43
    case ConstructionContext::LambdaCaptureKind: {
312
43
      CallOpts.IsTemporaryCtorOrDtor = true;
313
314
43
      const auto *LCC = cast<LambdaCaptureConstructionContext>(CC);
315
316
43
      SVal Base = loc::MemRegionVal(
317
43
          MRMgr.getCXXTempObjectRegion(LCC->getInitializer(), LCtx));
318
319
43
      const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E);
320
43
      if (getIndexOfElementToConstruct(State, CE, LCtx)) {
321
33
        CallOpts.IsArrayCtorOrDtor = true;
322
33
        Base = State->getLValue(E->getType(), svalBuilder.makeArrayIndex(Idx),
323
33
                                Base);
324
33
      }
325
326
43
      return Base;
327
2.13k
    }
328
11.0k
    case ConstructionContext::ArgumentKind: {
329
      // Arguments are technically temporaries.
330
11.0k
      CallOpts.IsTemporaryCtorOrDtor = true;
331
332
11.0k
      const auto *ACC = cast<ArgumentConstructionContext>(CC);
333
11.0k
      const Expr *E = ACC->getCallLikeExpr();
334
11.0k
      unsigned Idx = ACC->getIndex();
335
336
11.0k
      CallEventManager &CEMgr = getStateManager().getCallEventManager();
337
11.0k
      auto getArgLoc = [&](CallEventRef<> Caller) -> std::optional<SVal> {
338
11.0k
        const LocationContext *FutureSFC =
339
11.0k
            Caller->getCalleeStackFrame(BldrCtx->blockCount());
340
        // Return early if we are unable to reliably foresee
341
        // the future stack frame.
342
11.0k
        if (!FutureSFC)
343
0
          return std::nullopt;
344
345
        // This should be equivalent to Caller->getDecl() for now, but
346
        // FutureSFC->getDecl() is likely to support better stuff (like
347
        // virtual functions) earlier.
348
11.0k
        const Decl *CalleeD = FutureSFC->getDecl();
349
350
        // FIXME: Support for variadic arguments is not implemented here yet.
351
11.0k
        if (CallEvent::isVariadic(CalleeD))
352
0
          return std::nullopt;
353
354
        // Operator arguments do not correspond to operator parameters
355
        // because this-argument is implemented as a normal argument in
356
        // operator call expressions but not in operator declarations.
357
11.0k
        const TypedValueRegion *TVR = Caller->getParameterLocation(
358
11.0k
            *Caller->getAdjustedParameterIndex(Idx), BldrCtx->blockCount());
359
11.0k
        if (!TVR)
360
0
          return std::nullopt;
361
362
11.0k
        return loc::MemRegionVal(TVR);
363
11.0k
      };
364
365
11.0k
      if (const auto *CE = dyn_cast<CallExpr>(E)) {
366
11.0k
        CallEventRef<> Caller =
367
11.0k
            CEMgr.getSimpleCall(CE, State, LCtx, getCFGElementRef());
368
11.0k
        if (std::optional<SVal> V = getArgLoc(Caller))
369
11.0k
          return *V;
370
0
        else
371
0
          break;
372
11.0k
      } else 
if (const auto *58
CCE58
= dyn_cast<CXXConstructExpr>(E)) {
373
        // Don't bother figuring out the target region for the future
374
        // constructor because we won't need it.
375
48
        CallEventRef<> Caller = CEMgr.getCXXConstructorCall(
376
48
            CCE, /*Target=*/nullptr, State, LCtx, getCFGElementRef());
377
48
        if (std::optional<SVal> V = getArgLoc(Caller))
378
48
          return *V;
379
0
        else
380
0
          break;
381
48
      } else 
if (const auto *10
ME10
= dyn_cast<ObjCMessageExpr>(E)) {
382
10
        CallEventRef<> Caller =
383
10
            CEMgr.getObjCMethodCall(ME, State, LCtx, getCFGElementRef());
384
10
        if (std::optional<SVal> V = getArgLoc(Caller))
385
10
          return *V;
386
0
        else
387
0
          break;
388
10
      }
389
11.0k
    }
390
33.0k
    } // switch (CC->getKind())
391
33.0k
  }
392
393
  // If we couldn't find an existing region to construct into, assume we're
394
  // constructing a temporary. Notify the caller of our failure.
395
635
  CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion = true;
396
635
  return loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx));
397
33.3k
}
398
399
ProgramStateRef ExprEngine::updateObjectsUnderConstruction(
400
    SVal V, const Expr *E, ProgramStateRef State, const LocationContext *LCtx,
401
33.2k
    const ConstructionContext *CC, const EvalCallOptions &CallOpts) {
402
33.2k
  if (CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion) {
403
    // Sounds like we failed to find the target region and therefore
404
    // copy elision failed. There's nothing we can do about it here.
405
505
    return State;
406
505
  }
407
408
  // See if we're constructing an existing region by looking at the
409
  // current construction context.
410
32.7k
  assert(CC && "Computed target region without construction context?");
411
32.7k
  switch (CC->getKind()) {
412
38
  case ConstructionContext::CXX17ElidedCopyVariableKind:
413
7.76k
  case ConstructionContext::SimpleVariableKind: {
414
7.76k
    const auto *DSCC = cast<VariableConstructionContext>(CC);
415
7.76k
    return addObjectUnderConstruction(State, DSCC->getDeclStmt(), LCtx, V);
416
38
    }
417
4
    case ConstructionContext::CXX17ElidedCopyConstructorInitializerKind:
418
2.82k
    case ConstructionContext::SimpleConstructorInitializerKind: {
419
2.82k
      const auto *ICC = cast<ConstructorInitializerConstructionContext>(CC);
420
2.82k
      const auto *Init = ICC->getCXXCtorInitializer();
421
      // Base and delegating initializers handled above
422
2.82k
      assert(Init->isAnyMemberInitializer() &&
423
2.82k
             "Base and delegating initializers should have been handled by"
424
2.82k
             "computeObjectUnderConstruction()");
425
2.82k
      return addObjectUnderConstruction(State, Init, LCtx, V);
426
2.82k
    }
427
580
    case ConstructionContext::NewAllocatedObjectKind: {
428
580
      return State;
429
2.82k
    }
430
2.16k
    case ConstructionContext::SimpleReturnedValueKind:
431
2.21k
    case ConstructionContext::CXX17ElidedCopyReturnedValueKind: {
432
2.21k
      const StackFrameContext *SFC = LCtx->getStackFrame();
433
2.21k
      const LocationContext *CallerLCtx = SFC->getParent();
434
2.21k
      if (!CallerLCtx) {
435
        // No extra work is necessary in top frame.
436
56
        return State;
437
56
      }
438
439
2.15k
      auto RTC = (*SFC->getCallSiteBlock())[SFC->getIndex()]
440
2.15k
                     .getAs<CFGCXXRecordTypedCall>();
441
2.15k
      assert(RTC && "Could not have had a target region without it");
442
2.15k
      if (isa<BlockInvocationContext>(CallerLCtx)) {
443
        // Unwrap block invocation contexts. They're mostly part of
444
        // the current stack frame.
445
1
        CallerLCtx = CallerLCtx->getParent();
446
1
        assert(!isa<BlockInvocationContext>(CallerLCtx));
447
1
      }
448
449
2.15k
      return updateObjectsUnderConstruction(V,
450
2.15k
          cast<Expr>(SFC->getCallSite()), State, CallerLCtx,
451
2.15k
          RTC->getConstructionContext(), CallOpts);
452
2.15k
    }
453
6.21k
    case ConstructionContext::ElidedTemporaryObjectKind: {
454
6.21k
      assert(AMgr.getAnalyzerOptions().ShouldElideConstructors);
455
6.21k
      if (!CallOpts.IsElidableCtorThatHasNotBeenElided) {
456
6.08k
        const auto *TCC = cast<ElidedTemporaryObjectConstructionContext>(CC);
457
6.08k
        State = updateObjectsUnderConstruction(
458
6.08k
            V, TCC->getConstructorAfterElision(), State, LCtx,
459
6.08k
            TCC->getConstructionContextAfterElision(), CallOpts);
460
461
        // Remember that we've elided the constructor.
462
6.08k
        State = addObjectUnderConstruction(
463
6.08k
            State, TCC->getConstructorAfterElision(), LCtx, V);
464
465
        // Remember that we've elided the destructor.
466
6.08k
        if (const auto *BTE = TCC->getCXXBindTemporaryExpr())
467
334
          State = elideDestructor(State, BTE, LCtx);
468
469
        // Instead of materialization, shamelessly return
470
        // the final object destination.
471
6.08k
        if (const auto *MTE = TCC->getMaterializedTemporaryExpr())
472
6.08k
          State = addObjectUnderConstruction(State, MTE, LCtx, V);
473
474
6.08k
        return State;
475
6.08k
      }
476
      // If we decided not to elide the constructor, proceed as if
477
      // it's a simple temporary.
478
6.21k
      [[fallthrough]];
479
130
    }
480
2.13k
    case ConstructionContext::SimpleTemporaryObjectKind: {
481
2.13k
      const auto *TCC = cast<TemporaryObjectConstructionContext>(CC);
482
2.13k
      if (const auto *BTE = TCC->getCXXBindTemporaryExpr())
483
353
        State = addObjectUnderConstruction(State, BTE, LCtx, V);
484
485
2.13k
      if (const auto *MTE = TCC->getMaterializedTemporaryExpr())
486
2.01k
        State = addObjectUnderConstruction(State, MTE, LCtx, V);
487
488
2.13k
      return State;
489
130
    }
490
43
    case ConstructionContext::LambdaCaptureKind: {
491
43
      const auto *LCC = cast<LambdaCaptureConstructionContext>(CC);
492
493
      // If we capture and array, we want to store the super region, not a
494
      // sub-region.
495
43
      if (const auto *EL = dyn_cast_or_null<ElementRegion>(V.getAsRegion()))
496
33
        V = loc::MemRegionVal(EL->getSuperRegion());
497
498
43
      return addObjectUnderConstruction(
499
43
          State, {LCC->getLambdaExpr(), LCC->getIndex()}, LCtx, V);
500
130
    }
501
11.0k
    case ConstructionContext::ArgumentKind: {
502
11.0k
      const auto *ACC = cast<ArgumentConstructionContext>(CC);
503
11.0k
      if (const auto *BTE = ACC->getCXXBindTemporaryExpr())
504
293
        State = addObjectUnderConstruction(State, BTE, LCtx, V);
505
506
11.0k
      return addObjectUnderConstruction(
507
11.0k
          State, {ACC->getCallLikeExpr(), ACC->getIndex()}, LCtx, V);
508
130
    }
509
32.7k
  }
510
0
  llvm_unreachable("Unhandled construction context!");
511
0
}
512
513
static ProgramStateRef
514
bindRequiredArrayElementToEnvironment(ProgramStateRef State,
515
                                      const ArrayInitLoopExpr *AILE,
516
106
                                      const LocationContext *LCtx, SVal Idx) {
517
  // The ctor in this case is guaranteed to be a copy ctor, otherwise we hit a
518
  // compile time error.
519
  //
520
  //  -ArrayInitLoopExpr                <-- we're here
521
  //   |-OpaqueValueExpr
522
  //   | `-DeclRefExpr                  <-- match this
523
  //   `-CXXConstructExpr
524
  //     `-ImplicitCastExpr
525
  //       `-ArraySubscriptExpr
526
  //         |-ImplicitCastExpr
527
  //         | `-OpaqueValueExpr
528
  //         |   `-DeclRefExpr
529
  //         `-ArrayInitIndexExpr
530
  //
531
  // The resulting expression might look like the one below in an implicit
532
  // copy/move ctor.
533
  //
534
  //   ArrayInitLoopExpr                <-- we're here
535
  //   |-OpaqueValueExpr
536
  //   | `-MemberExpr                   <-- match this
537
  //   |  (`-CXXStaticCastExpr)         <-- move ctor only
538
  //   |     `-DeclRefExpr
539
  //   `-CXXConstructExpr
540
  //     `-ArraySubscriptExpr
541
  //       |-ImplicitCastExpr
542
  //       | `-OpaqueValueExpr
543
  //       |   `-MemberExpr
544
  //       |     `-DeclRefExpr
545
  //       `-ArrayInitIndexExpr
546
  //
547
  // The resulting expression for a multidimensional array.
548
  // ArrayInitLoopExpr                  <-- we're here
549
  // |-OpaqueValueExpr
550
  // | `-DeclRefExpr                    <-- match this
551
  // `-ArrayInitLoopExpr
552
  //   |-OpaqueValueExpr
553
  //   | `-ArraySubscriptExpr
554
  //   |   |-ImplicitCastExpr
555
  //   |   | `-OpaqueValueExpr
556
  //   |   |   `-DeclRefExpr
557
  //   |   `-ArrayInitIndexExpr
558
  //   `-CXXConstructExpr             <-- extract this
559
  //     ` ...
560
561
106
  const auto *OVESrc = AILE->getCommonExpr()->getSourceExpr();
562
563
  // HACK: There is no way we can put the index of the array element into the
564
  // CFG unless we unroll the loop, so we manually select and bind the required
565
  // parameter to the environment.
566
106
  const auto *CE =
567
106
      cast<CXXConstructExpr>(extractElementInitializerFromNestedAILE(AILE));
568
569
106
  SVal Base = UnknownVal();
570
106
  if (const auto *ME = dyn_cast<MemberExpr>(OVESrc))
571
60
    Base = State->getSVal(ME, LCtx);
572
46
  else if (const auto *DRE = dyn_cast<DeclRefExpr>(OVESrc))
573
46
    Base = State->getLValue(cast<VarDecl>(DRE->getDecl()), LCtx);
574
0
  else
575
0
    llvm_unreachable("ArrayInitLoopExpr contains unexpected source expression");
576
577
106
  SVal NthElem = State->getLValue(CE->getType(), Idx, Base);
578
579
106
  return State->BindExpr(CE->getArg(0), LCtx, NthElem);
580
106
}
581
582
void ExprEngine::handleConstructor(const Expr *E,
583
                                   ExplodedNode *Pred,
584
29.8k
                                   ExplodedNodeSet &destNodes) {
585
29.8k
  const auto *CE = dyn_cast<CXXConstructExpr>(E);
586
29.8k
  const auto *CIE = dyn_cast<CXXInheritedCtorInitExpr>(E);
587
29.8k
  assert(CE || CIE);
588
589
29.8k
  const LocationContext *LCtx = Pred->getLocationContext();
590
29.8k
  ProgramStateRef State = Pred->getState();
591
592
29.8k
  SVal Target = UnknownVal();
593
594
29.8k
  if (CE) {
595
29.8k
    if (std::optional<SVal> ElidedTarget =
596
29.8k
            getObjectUnderConstruction(State, CE, LCtx)) {
597
        // We've previously modeled an elidable constructor by pretending that
598
        // it in fact constructs into the correct target. This constructor can
599
        // therefore be skipped.
600
6.08k
        Target = *ElidedTarget;
601
6.08k
        StmtNodeBuilder Bldr(Pred, destNodes, *currBldrCtx);
602
6.08k
        State = finishObjectConstruction(State, CE, LCtx);
603
6.08k
        if (auto L = Target.getAs<Loc>())
604
6.08k
          State = State->BindExpr(CE, LCtx, State->getSVal(*L, CE->getType()));
605
6.08k
        Bldr.generateNode(CE, Pred, State);
606
6.08k
        return;
607
6.08k
    }
608
29.8k
  }
609
610
23.7k
  EvalCallOptions CallOpts;
611
23.7k
  auto C = getCurrentCFGElement().getAs<CFGConstructor>();
612
23.7k
  assert(C || getCurrentCFGElement().getAs<CFGStmt>());
613
23.7k
  const ConstructionContext *CC = C ? 
C->getConstructionContext()23.4k
:
nullptr323
;
614
615
23.7k
  const CXXConstructExpr::ConstructionKind CK =
616
23.7k
      CE ? 
CE->getConstructionKind()23.7k
:
CIE->getConstructionKind()5
;
617
23.7k
  switch (CK) {
618
22.9k
  case CXXConstructExpr::CK_Complete: {
619
    // Inherited constructors are always base class constructors.
620
22.9k
    assert(CE && !CIE && "A complete constructor is inherited?!");
621
622
    // If the ctor is part of an ArrayInitLoopExpr, we want to handle it
623
    // differently.
624
22.9k
    auto *AILE = CC ? 
CC->getArrayInitLoop()22.6k
:
nullptr294
;
625
626
22.9k
    unsigned Idx = 0;
627
22.9k
    if (CE->getType()->isArrayType() || 
AILE22.4k
) {
628
629
684
      auto isZeroSizeArray = [&] {
630
684
        uint64_t Size = 1;
631
632
684
        if (const auto *CAT = dyn_cast<ConstantArrayType>(CE->getType()))
633
564
          Size = getContext().getConstantArrayElementCount(CAT);
634
120
        else if (AILE)
635
115
          Size = getContext().getArrayInitLoopExprElementCount(AILE);
636
637
684
        return Size == 0;
638
684
      };
639
640
      // No element construction will happen in a 0 size array.
641
684
      if (isZeroSizeArray()) {
642
50
        StmtNodeBuilder Bldr(Pred, destNodes, *currBldrCtx);
643
50
        static SimpleProgramPointTag T{"ExprEngine",
644
50
                                       "Skipping 0 size array construction"};
645
50
        Bldr.generateNode(CE, Pred, State, &T);
646
50
        return;
647
50
      }
648
649
634
      Idx = getIndexOfElementToConstruct(State, CE, LCtx).value_or(0u);
650
634
      State = setIndexOfElementToConstruct(State, CE, LCtx, Idx + 1);
651
634
    }
652
653
22.9k
    if (AILE) {
654
      // Only set this once even though we loop through it multiple times.
655
106
      if (!getPendingInitLoop(State, CE, LCtx))
656
39
        State = setPendingInitLoop(
657
39
            State, CE, LCtx,
658
39
            getContext().getArrayInitLoopExprElementCount(AILE));
659
660
106
      State = bindRequiredArrayElementToEnvironment(
661
106
          State, AILE, LCtx, svalBuilder.makeArrayIndex(Idx));
662
106
    }
663
664
    // The target region is found from construction context.
665
22.9k
    std::tie(State, Target) = handleConstructionContext(
666
22.9k
        CE, State, currBldrCtx, LCtx, CC, CallOpts, Idx);
667
22.9k
    break;
668
22.9k
  }
669
116
  case CXXConstructExpr::CK_VirtualBase: {
670
    // Make sure we are not calling virtual base class initializers twice.
671
    // Only the most-derived object should initialize virtual base classes.
672
116
    const auto *OuterCtor = dyn_cast_or_null<CXXConstructExpr>(
673
116
        LCtx->getStackFrame()->getCallSite());
674
116
    assert(
675
116
        (!OuterCtor ||
676
116
         OuterCtor->getConstructionKind() == CXXConstructExpr::CK_Complete ||
677
116
         OuterCtor->getConstructionKind() == CXXConstructExpr::CK_Delegating) &&
678
116
        ("This virtual base should have already been initialized by "
679
116
         "the most derived class!"));
680
116
    (void)OuterCtor;
681
116
    [[fallthrough]];
682
116
  }
683
767
  case CXXConstructExpr::CK_NonVirtualBase:
684
    // In C++17, classes with non-virtual bases may be aggregates, so they would
685
    // be initialized as aggregates without a constructor call, so we may have
686
    // a base class constructed directly into an initializer list without
687
    // having the derived-class constructor call on the previous stack frame.
688
    // Initializer lists may be nested into more initializer lists that
689
    // correspond to surrounding aggregate initializations.
690
    // FIXME: For now this code essentially bails out. We need to find the
691
    // correct target region and set it.
692
    // FIXME: Instead of relying on the ParentMap, we should have the
693
    // trigger-statement (InitListExpr in this case) passed down from CFG or
694
    // otherwise always available during construction.
695
767
    if (isa_and_nonnull<InitListExpr>(LCtx->getParentMap().getParent(E))) {
696
24
      MemRegionManager &MRMgr = getSValBuilder().getRegionManager();
697
24
      Target = loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx));
698
24
      CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion = true;
699
24
      break;
700
24
    }
701
767
    
[[fallthrough]];743
702
758
  case CXXConstructExpr::CK_Delegating: {
703
758
    const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
704
758
    Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor,
705
758
                                              LCtx->getStackFrame());
706
758
    SVal ThisVal = State->getSVal(ThisPtr);
707
708
758
    if (CK == CXXConstructExpr::CK_Delegating) {
709
15
      Target = ThisVal;
710
743
    } else {
711
      // Cast to the base type.
712
743
      bool IsVirtual = (CK == CXXConstructExpr::CK_VirtualBase);
713
743
      SVal BaseVal =
714
743
          getStoreManager().evalDerivedToBase(ThisVal, E->getType(), IsVirtual);
715
743
      Target = BaseVal;
716
743
    }
717
758
    break;
718
743
  }
719
23.7k
  }
720
721
23.7k
  if (State != Pred->getState()) {
722
21.9k
    static SimpleProgramPointTag T("ExprEngine",
723
21.9k
                                   "Prepare for object construction");
724
21.9k
    ExplodedNodeSet DstPrepare;
725
21.9k
    StmtNodeBuilder BldrPrepare(Pred, DstPrepare, *currBldrCtx);
726
21.9k
    BldrPrepare.generateNode(E, Pred, State, &T, ProgramPoint::PreStmtKind);
727
21.9k
    assert(DstPrepare.size() <= 1);
728
21.9k
    if (DstPrepare.size() == 0)
729
27
      return;
730
21.9k
    Pred = *BldrPrepare.begin();
731
21.9k
  }
732
733
23.6k
  const MemRegion *TargetRegion = Target.getAsRegion();
734
23.6k
  CallEventManager &CEMgr = getStateManager().getCallEventManager();
735
23.6k
  CallEventRef<> Call =
736
23.6k
      CIE ? (CallEventRef<>)CEMgr.getCXXInheritedConstructorCall(
737
5
                CIE, TargetRegion, State, LCtx, getCFGElementRef())
738
23.6k
          : (CallEventRef<>)CEMgr.getCXXConstructorCall(
739
23.6k
                CE, TargetRegion, State, LCtx, getCFGElementRef());
740
741
23.6k
  ExplodedNodeSet DstPreVisit;
742
23.6k
  getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, E, *this);
743
744
23.6k
  ExplodedNodeSet PreInitialized;
745
23.6k
  if (CE) {
746
    // FIXME: Is it possible and/or useful to do this before PreStmt?
747
23.6k
    StmtNodeBuilder Bldr(DstPreVisit, PreInitialized, *currBldrCtx);
748
23.6k
    for (ExplodedNode *N : DstPreVisit) {
749
23.6k
      ProgramStateRef State = N->getState();
750
23.6k
      if (CE->requiresZeroInitialization()) {
751
        // FIXME: Once we properly handle constructors in new-expressions, we'll
752
        // need to invalidate the region before setting a default value, to make
753
        // sure there aren't any lingering bindings around. This probably needs
754
        // to happen regardless of whether or not the object is zero-initialized
755
        // to handle random fields of a placement-initialized object picking up
756
        // old bindings. We might only want to do it when we need to, though.
757
        // FIXME: This isn't actually correct for arrays -- we need to zero-
758
        // initialize the entire array, not just the first element -- but our
759
        // handling of arrays everywhere else is weak as well, so this shouldn't
760
        // actually make things worse. Placement new makes this tricky as well,
761
        // since it's then possible to be initializing one part of a multi-
762
        // dimensional array.
763
1.98k
        State = State->bindDefaultZero(Target, LCtx);
764
1.98k
      }
765
766
23.6k
      Bldr.generateNode(CE, N, State, /*tag=*/nullptr,
767
23.6k
                        ProgramPoint::PreStmtKind);
768
23.6k
    }
769
23.6k
  } else {
770
5
    PreInitialized = DstPreVisit;
771
5
  }
772
773
23.6k
  ExplodedNodeSet DstPreCall;
774
23.6k
  getCheckerManager().runCheckersForPreCall(DstPreCall, PreInitialized,
775
23.6k
                                            *Call, *this);
776
777
23.6k
  ExplodedNodeSet DstEvaluated;
778
779
23.6k
  if (CE && 
CE->getConstructor()->isTrivial()23.6k
&&
780
23.6k
      
CE->getConstructor()->isCopyOrMoveConstructor()15.5k
&&
781
23.6k
      
!CallOpts.IsArrayCtorOrDtor12.5k
) {
782
12.5k
    StmtNodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx);
783
    // FIXME: Handle other kinds of trivial constructors as well.
784
12.5k
    for (ExplodedNode *N : DstPreCall)
785
12.5k
      performTrivialCopy(Bldr, N, *Call);
786
787
12.5k
  } else {
788
11.1k
    for (ExplodedNode *N : DstPreCall)
789
11.1k
      getCheckerManager().runCheckersForEvalCall(DstEvaluated, N, *Call, *this,
790
11.1k
                                                 CallOpts);
791
11.1k
  }
792
793
  // If the CFG was constructed without elements for temporary destructors
794
  // and the just-called constructor created a temporary object then
795
  // stop exploration if the temporary object has a noreturn constructor.
796
  // This can lose coverage because the destructor, if it were present
797
  // in the CFG, would be called at the end of the full expression or
798
  // later (for life-time extended temporaries) -- but avoids infeasible
799
  // paths when no-return temporary destructors are used for assertions.
800
23.6k
  ExplodedNodeSet DstEvaluatedPostProcessed;
801
23.6k
  StmtNodeBuilder Bldr(DstEvaluated, DstEvaluatedPostProcessed, *currBldrCtx);
802
23.6k
  const AnalysisDeclContext *ADC = LCtx->getAnalysisDeclContext();
803
23.6k
  if (!ADC->getCFGBuildOptions().AddTemporaryDtors) {
804
283
    if (llvm::isa_and_nonnull<CXXTempObjectRegion,
805
283
                              CXXLifetimeExtendedObjectRegion>(TargetRegion) &&
806
283
        cast<CXXConstructorDecl>(Call->getDecl())
807
110
            ->getParent()
808
110
            ->isAnyDestructorNoReturn()) {
809
810
      // If we've inlined the constructor, then DstEvaluated would be empty.
811
      // In this case we still want a sink, which could be implemented
812
      // in processCallExit. But we don't have that implemented at the moment,
813
      // so if you hit this assertion, see if you can avoid inlining
814
      // the respective constructor when analyzer-config cfg-temporary-dtors
815
      // is set to false.
816
      // Otherwise there's nothing wrong with inlining such constructor.
817
4
      assert(!DstEvaluated.empty() &&
818
4
             "We should not have inlined this constructor!");
819
820
4
      for (ExplodedNode *N : DstEvaluated) {
821
4
        Bldr.generateSink(E, N, N->getState());
822
4
      }
823
824
      // There is no need to run the PostCall and PostStmt checker
825
      // callbacks because we just generated sinks on all nodes in th
826
      // frontier.
827
4
      return;
828
4
    }
829
283
  }
830
831
23.6k
  ExplodedNodeSet DstPostArgumentCleanup;
832
23.6k
  for (ExplodedNode *I : DstEvaluatedPostProcessed)
833
14.2k
    finishArgumentConstruction(DstPostArgumentCleanup, I, *Call);
834
835
  // If there were other constructors called for object-type arguments
836
  // of this constructor, clean them up.
837
23.6k
  ExplodedNodeSet DstPostCall;
838
23.6k
  getCheckerManager().runCheckersForPostCall(DstPostCall,
839
23.6k
                                             DstPostArgumentCleanup,
840
23.6k
                                             *Call, *this);
841
23.6k
  getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, E, *this);
842
23.6k
}
843
844
void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE,
845
                                       ExplodedNode *Pred,
846
29.8k
                                       ExplodedNodeSet &Dst) {
847
29.8k
  handleConstructor(CE, Pred, Dst);
848
29.8k
}
849
850
void ExprEngine::VisitCXXInheritedCtorInitExpr(
851
    const CXXInheritedCtorInitExpr *CE, ExplodedNode *Pred,
852
5
    ExplodedNodeSet &Dst) {
853
5
  handleConstructor(CE, Pred, Dst);
854
5
}
855
856
void ExprEngine::VisitCXXDestructor(QualType ObjectType,
857
                                    const MemRegion *Dest,
858
                                    const Stmt *S,
859
                                    bool IsBaseDtor,
860
                                    ExplodedNode *Pred,
861
                                    ExplodedNodeSet &Dst,
862
1.79k
                                    EvalCallOptions &CallOpts) {
863
1.79k
  assert(S && "A destructor without a trigger!");
864
1.79k
  const LocationContext *LCtx = Pred->getLocationContext();
865
1.79k
  ProgramStateRef State = Pred->getState();
866
867
1.79k
  const CXXRecordDecl *RecordDecl = ObjectType->getAsCXXRecordDecl();
868
1.79k
  assert(RecordDecl && "Only CXXRecordDecls should have destructors");
869
1.79k
  const CXXDestructorDecl *DtorDecl = RecordDecl->getDestructor();
870
  // FIXME: There should always be a Decl, otherwise the destructor call
871
  // shouldn't have been added to the CFG in the first place.
872
1.79k
  if (!DtorDecl) {
873
    // Skip the invalid destructor. We cannot simply return because
874
    // it would interrupt the analysis instead.
875
1
    static SimpleProgramPointTag T("ExprEngine", "SkipInvalidDestructor");
876
    // FIXME: PostImplicitCall with a null decl may crash elsewhere anyway.
877
1
    PostImplicitCall PP(/*Decl=*/nullptr, S->getEndLoc(), LCtx,
878
1
                        getCFGElementRef(), &T);
879
1
    NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
880
1
    Bldr.generateNode(PP, Pred->getState(), Pred);
881
1
    return;
882
1
  }
883
884
1.79k
  if (!Dest) {
885
    // We're trying to destroy something that is not a region. This may happen
886
    // for a variety of reasons (unknown target region, concrete integer instead
887
    // of target region, etc.). The current code makes an attempt to recover.
888
    // FIXME: We probably don't really need to recover when we're dealing
889
    // with concrete integers specifically.
890
78
    CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion = true;
891
78
    if (const Expr *E = dyn_cast_or_null<Expr>(S)) {
892
76
      Dest = MRMgr.getCXXTempObjectRegion(E, Pred->getLocationContext());
893
76
    } else {
894
2
      static SimpleProgramPointTag T("ExprEngine", "SkipInvalidDestructor");
895
2
      NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
896
2
      Bldr.generateSink(Pred->getLocation().withTag(&T),
897
2
                        Pred->getState(), Pred);
898
2
      return;
899
2
    }
900
78
  }
901
902
1.78k
  CallEventManager &CEMgr = getStateManager().getCallEventManager();
903
1.78k
  CallEventRef<CXXDestructorCall> Call = CEMgr.getCXXDestructorCall(
904
1.78k
      DtorDecl, S, Dest, IsBaseDtor, State, LCtx, getCFGElementRef());
905
906
1.78k
  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
907
1.78k
                                Call->getSourceRange().getBegin(),
908
1.78k
                                "Error evaluating destructor");
909
910
1.78k
  ExplodedNodeSet DstPreCall;
911
1.78k
  getCheckerManager().runCheckersForPreCall(DstPreCall, Pred,
912
1.78k
                                            *Call, *this);
913
914
1.78k
  ExplodedNodeSet DstInvalidated;
915
1.78k
  StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);
916
1.78k
  for (ExplodedNode *N : DstPreCall)
917
1.77k
    defaultEvalCall(Bldr, N, *Call, CallOpts);
918
919
1.78k
  getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated,
920
1.78k
                                             *Call, *this);
921
1.78k
}
922
923
void ExprEngine::VisitCXXNewAllocatorCall(const CXXNewExpr *CNE,
924
                                          ExplodedNode *Pred,
925
1.09k
                                          ExplodedNodeSet &Dst) {
926
1.09k
  ProgramStateRef State = Pred->getState();
927
1.09k
  const LocationContext *LCtx = Pred->getLocationContext();
928
1.09k
  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
929
1.09k
                                CNE->getBeginLoc(),
930
1.09k
                                "Error evaluating New Allocator Call");
931
1.09k
  CallEventManager &CEMgr = getStateManager().getCallEventManager();
932
1.09k
  CallEventRef<CXXAllocatorCall> Call =
933
1.09k
      CEMgr.getCXXAllocatorCall(CNE, State, LCtx, getCFGElementRef());
934
935
1.09k
  ExplodedNodeSet DstPreCall;
936
1.09k
  getCheckerManager().runCheckersForPreCall(DstPreCall, Pred,
937
1.09k
                                            *Call, *this);
938
939
1.09k
  ExplodedNodeSet DstPostCall;
940
1.09k
  StmtNodeBuilder CallBldr(DstPreCall, DstPostCall, *currBldrCtx);
941
1.09k
  for (ExplodedNode *I : DstPreCall) {
942
    // FIXME: Provide evalCall for checkers?
943
1.07k
    defaultEvalCall(CallBldr, I, *Call);
944
1.07k
  }
945
  // If the call is inlined, DstPostCall will be empty and we bail out now.
946
947
  // Store return value of operator new() for future use, until the actual
948
  // CXXNewExpr gets processed.
949
1.09k
  ExplodedNodeSet DstPostValue;
950
1.09k
  StmtNodeBuilder ValueBldr(DstPostCall, DstPostValue, *currBldrCtx);
951
1.09k
  for (ExplodedNode *I : DstPostCall) {
952
    // FIXME: Because CNE serves as the "call site" for the allocator (due to
953
    // lack of a better expression in the AST), the conjured return value symbol
954
    // is going to be of the same type (C++ object pointer type). Technically
955
    // this is not correct because the operator new's prototype always says that
956
    // it returns a 'void *'. So we should change the type of the symbol,
957
    // and then evaluate the cast over the symbolic pointer from 'void *' to
958
    // the object pointer type. But without changing the symbol's type it
959
    // is breaking too much to evaluate the no-op symbolic cast over it, so we
960
    // skip it for now.
961
845
    ProgramStateRef State = I->getState();
962
845
    SVal RetVal = State->getSVal(CNE, LCtx);
963
    // [basic.stc.dynamic.allocation] (on the return value of an allocation
964
    // function):
965
    // "The order, contiguity, and initial value of storage allocated by
966
    // successive calls to an allocation function are unspecified."
967
845
    State = State->bindDefaultInitial(RetVal, UndefinedVal{}, LCtx);
968
969
    // If this allocation function is not declared as non-throwing, failures
970
    // /must/ be signalled by exceptions, and thus the return value will never
971
    // be NULL. -fno-exceptions does not influence this semantics.
972
    // FIXME: GCC has a -fcheck-new option, which forces it to consider the case
973
    // where new can return NULL. If we end up supporting that option, we can
974
    // consider adding a check for it here.
975
    // C++11 [basic.stc.dynamic.allocation]p3.
976
845
    if (const FunctionDecl *FD = CNE->getOperatorNew()) {
977
845
      QualType Ty = FD->getType();
978
845
      if (const auto *ProtoType = Ty->getAs<FunctionProtoType>())
979
845
        if (!ProtoType->isNothrow())
980
818
          State = State->assume(RetVal.castAs<DefinedOrUnknownSVal>(), true);
981
845
    }
982
983
845
    ValueBldr.generateNode(
984
845
        CNE, I, addObjectUnderConstruction(State, CNE, LCtx, RetVal));
985
845
  }
986
987
1.09k
  ExplodedNodeSet DstPostPostCallCallback;
988
1.09k
  getCheckerManager().runCheckersForPostCall(DstPostPostCallCallback,
989
1.09k
                                             DstPostValue, *Call, *this);
990
1.09k
  for (ExplodedNode *I : DstPostPostCallCallback) {
991
845
    getCheckerManager().runCheckersForNewAllocator(*Call, Dst, I, *this);
992
845
  }
993
1.09k
}
994
995
void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
996
1.05k
                                   ExplodedNodeSet &Dst) {
997
  // FIXME: Much of this should eventually migrate to CXXAllocatorCall.
998
  // Also, we need to decide how allocators actually work -- they're not
999
  // really part of the CXXNewExpr because they happen BEFORE the
1000
  // CXXConstructExpr subexpression. See PR12014 for some discussion.
1001
1002
1.05k
  unsigned blockCount = currBldrCtx->blockCount();
1003
1.05k
  const LocationContext *LCtx = Pred->getLocationContext();
1004
1.05k
  SVal symVal = UnknownVal();
1005
1.05k
  FunctionDecl *FD = CNE->getOperatorNew();
1006
1007
1.05k
  bool IsStandardGlobalOpNewFunction =
1008
1.05k
      FD->isReplaceableGlobalAllocationFunction();
1009
1010
1.05k
  ProgramStateRef State = Pred->getState();
1011
1012
  // Retrieve the stored operator new() return value.
1013
1.05k
  if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
1014
1.05k
    symVal = *getObjectUnderConstruction(State, CNE, LCtx);
1015
1.05k
    State = finishObjectConstruction(State, CNE, LCtx);
1016
1.05k
  }
1017
1018
  // We assume all standard global 'operator new' functions allocate memory in
1019
  // heap. We realize this is an approximation that might not correctly model
1020
  // a custom global allocator.
1021
1.05k
  if (symVal.isUnknown()) {
1022
7
    if (IsStandardGlobalOpNewFunction)
1023
5
      symVal = svalBuilder.getConjuredHeapSymbolVal(CNE, LCtx, blockCount);
1024
2
    else
1025
2
      symVal = svalBuilder.conjureSymbolVal(nullptr, CNE, LCtx, CNE->getType(),
1026
2
                                            blockCount);
1027
7
  }
1028
1029
1.05k
  CallEventManager &CEMgr = getStateManager().getCallEventManager();
1030
1.05k
  CallEventRef<CXXAllocatorCall> Call =
1031
1.05k
      CEMgr.getCXXAllocatorCall(CNE, State, LCtx, getCFGElementRef());
1032
1033
1.05k
  if (!AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
1034
    // Invalidate placement args.
1035
    // FIXME: Once we figure out how we want allocators to work,
1036
    // we should be using the usual pre-/(default-)eval-/post-call checkers
1037
    // here.
1038
7
    State = Call->invalidateRegions(blockCount);
1039
7
    if (!State)
1040
0
      return;
1041
1042
    // If this allocation function is not declared as non-throwing, failures
1043
    // /must/ be signalled by exceptions, and thus the return value will never
1044
    // be NULL. -fno-exceptions does not influence this semantics.
1045
    // FIXME: GCC has a -fcheck-new option, which forces it to consider the case
1046
    // where new can return NULL. If we end up supporting that option, we can
1047
    // consider adding a check for it here.
1048
    // C++11 [basic.stc.dynamic.allocation]p3.
1049
7
    if (const auto *ProtoType = FD->getType()->getAs<FunctionProtoType>())
1050
7
      if (!ProtoType->isNothrow())
1051
3
        if (auto dSymVal = symVal.getAs<DefinedOrUnknownSVal>())
1052
3
          State = State->assume(*dSymVal, true);
1053
7
  }
1054
1055
1.05k
  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
1056
1057
1.05k
  SVal Result = symVal;
1058
1059
1.05k
  if (CNE->isArray()) {
1060
1061
187
    if (const auto *NewReg = cast_or_null<SubRegion>(symVal.getAsRegion())) {
1062
      // If each element is initialized by their default constructor, the field
1063
      // values are properly placed inside the required region, however if an
1064
      // initializer list is used, this doesn't happen automatically.
1065
182
      auto *Init = CNE->getInitializer();
1066
182
      bool isInitList = isa_and_nonnull<InitListExpr>(Init);
1067
1068
182
      QualType ObjTy =
1069
182
          isInitList ? 
Init->getType()1
:
CNE->getType()->getPointeeType()181
;
1070
182
      const ElementRegion *EleReg =
1071
182
          MRMgr.getElementRegion(ObjTy, svalBuilder.makeArrayIndex(0), NewReg,
1072
182
                                 svalBuilder.getContext());
1073
182
      Result = loc::MemRegionVal(EleReg);
1074
1075
      // If the array is list initialized, we bind the initializer list to the
1076
      // memory region here, otherwise we would lose it.
1077
182
      if (isInitList) {
1078
1
        Bldr.takeNodes(Pred);
1079
1
        Pred = Bldr.generateNode(CNE, Pred, State);
1080
1081
1
        SVal V = State->getSVal(Init, LCtx);
1082
1
        ExplodedNodeSet evaluated;
1083
1
        evalBind(evaluated, CNE, Pred, Result, V, true);
1084
1085
1
        Bldr.takeNodes(Pred);
1086
1
        Bldr.addNodes(evaluated);
1087
1088
1
        Pred = *evaluated.begin();
1089
1
        State = Pred->getState();
1090
1
      }
1091
182
    }
1092
1093
187
    State = State->BindExpr(CNE, Pred->getLocationContext(), Result);
1094
187
    Bldr.generateNode(CNE, Pred, State);
1095
187
    return;
1096
187
  }
1097
1098
  // FIXME: Once we have proper support for CXXConstructExprs inside
1099
  // CXXNewExpr, we need to make sure that the constructed object is not
1100
  // immediately invalidated here. (The placement call should happen before
1101
  // the constructor call anyway.)
1102
870
  if (FD->isReservedGlobalPlacementOperator()) {
1103
    // Non-array placement new should always return the placement location.
1104
160
    SVal PlacementLoc = State->getSVal(CNE->getPlacementArg(0), LCtx);
1105
160
    Result = svalBuilder.evalCast(PlacementLoc, CNE->getType(),
1106
160
                                  CNE->getPlacementArg(0)->getType());
1107
160
  }
1108
1109
  // Bind the address of the object, then check to see if we cached out.
1110
870
  State = State->BindExpr(CNE, LCtx, Result);
1111
870
  ExplodedNode *NewN = Bldr.generateNode(CNE, Pred, State);
1112
870
  if (!NewN)
1113
0
    return;
1114
1115
  // If the type is not a record, we won't have a CXXConstructExpr as an
1116
  // initializer. Copy the value over.
1117
870
  if (const Expr *Init = CNE->getInitializer()) {
1118
603
    if (!isa<CXXConstructExpr>(Init)) {
1119
148
      assert(Bldr.getResults().size() == 1);
1120
148
      Bldr.takeNodes(NewN);
1121
148
      evalBind(Dst, CNE, NewN, Result, State->getSVal(Init, LCtx),
1122
148
               /*FirstInit=*/IsStandardGlobalOpNewFunction);
1123
148
    }
1124
603
  }
1125
870
}
1126
1127
void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE,
1128
525
                                    ExplodedNode *Pred, ExplodedNodeSet &Dst) {
1129
1130
525
  CallEventManager &CEMgr = getStateManager().getCallEventManager();
1131
525
  CallEventRef<CXXDeallocatorCall> Call = CEMgr.getCXXDeallocatorCall(
1132
525
      CDE, Pred->getState(), Pred->getLocationContext(), getCFGElementRef());
1133
1134
525
  ExplodedNodeSet DstPreCall;
1135
525
  getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, *Call, *this);
1136
525
  ExplodedNodeSet DstPostCall;
1137
1138
525
  if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
1139
524
    StmtNodeBuilder Bldr(DstPreCall, DstPostCall, *currBldrCtx);
1140
524
    for (ExplodedNode *I : DstPreCall) {
1141
402
      defaultEvalCall(Bldr, I, *Call);
1142
402
    }
1143
524
  } else {
1144
1
    DstPostCall = DstPreCall;
1145
1
  }
1146
525
  getCheckerManager().runCheckersForPostCall(Dst, DstPostCall, *Call, *this);
1147
525
}
1148
1149
void ExprEngine::VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred,
1150
0
                                   ExplodedNodeSet &Dst) {
1151
0
  const VarDecl *VD = CS->getExceptionDecl();
1152
0
  if (!VD) {
1153
0
    Dst.Add(Pred);
1154
0
    return;
1155
0
  }
1156
1157
0
  const LocationContext *LCtx = Pred->getLocationContext();
1158
0
  SVal V = svalBuilder.conjureSymbolVal(CS, LCtx, VD->getType(),
1159
0
                                        currBldrCtx->blockCount());
1160
0
  ProgramStateRef state = Pred->getState();
1161
0
  state = state->bindLoc(state->getLValue(VD, LCtx), V, LCtx);
1162
1163
0
  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
1164
0
  Bldr.generateNode(CS, Pred, state);
1165
0
}
1166
1167
void ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
1168
9.25k
                                    ExplodedNodeSet &Dst) {
1169
9.25k
  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
1170
1171
  // Get the this object region from StoreManager.
1172
9.25k
  const LocationContext *LCtx = Pred->getLocationContext();
1173
9.25k
  const MemRegion *R =
1174
9.25k
    svalBuilder.getRegionManager().getCXXThisRegion(
1175
9.25k
                                  getContext().getCanonicalType(TE->getType()),
1176
9.25k
                                                    LCtx);
1177
1178
9.25k
  ProgramStateRef state = Pred->getState();
1179
9.25k
  SVal V = state->getSVal(loc::MemRegionVal(R));
1180
9.25k
  Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V));
1181
9.25k
}
1182
1183
void ExprEngine::VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred,
1184
539
                                 ExplodedNodeSet &Dst) {
1185
539
  const LocationContext *LocCtxt = Pred->getLocationContext();
1186
1187
  // Get the region of the lambda itself.
1188
539
  const MemRegion *R = svalBuilder.getRegionManager().getCXXTempObjectRegion(
1189
539
      LE, LocCtxt);
1190
539
  SVal V = loc::MemRegionVal(R);
1191
1192
539
  ProgramStateRef State = Pred->getState();
1193
1194
  // If we created a new MemRegion for the lambda, we should explicitly bind
1195
  // the captures.
1196
539
  for (auto const [Idx, FieldForCapture, InitExpr] :
1197
539
       llvm::zip(llvm::seq<unsigned>(0, -1), LE->getLambdaClass()->fields(),
1198
539
                 LE->capture_inits())) {
1199
258
    SVal FieldLoc = State->getLValue(FieldForCapture, V);
1200
1201
258
    SVal InitVal;
1202
258
    if (!FieldForCapture->hasCapturedVLAType()) {
1203
256
      assert(InitExpr && "Capture missing initialization expression");
1204
1205
      // Capturing a 0 length array is a no-op, so we ignore it to get a more
1206
      // accurate analysis. If it's not ignored, it would set the default
1207
      // binding of the lambda to 'Unknown', which can lead to falsely detecting
1208
      // 'Uninitialized' values as 'Unknown' and not reporting a warning.
1209
256
      const auto FTy = FieldForCapture->getType();
1210
256
      if (FTy->isConstantArrayType() &&
1211
256
          getContext().getConstantArrayElementCount(
1212
27
              getContext().getAsConstantArrayType(FTy)) == 0)
1213
8
        continue;
1214
1215
      // With C++17 copy elision the InitExpr can be anything, so instead of
1216
      // pattern matching all cases, we simple check if the current field is
1217
      // under construction or not, regardless what it's InitExpr is.
1218
248
      if (const auto OUC =
1219
248
              getObjectUnderConstruction(State, {LE, Idx}, LocCtxt)) {
1220
18
        InitVal = State->getSVal(OUC->getAsRegion());
1221
1222
18
        State = finishObjectConstruction(State, {LE, Idx}, LocCtxt);
1223
18
      } else
1224
230
        InitVal = State->getSVal(InitExpr, LocCtxt);
1225
1226
248
    } else {
1227
1228
2
      assert(!getObjectUnderConstruction(State, {LE, Idx}, LocCtxt) &&
1229
2
             "VLA capture by value is a compile time error!");
1230
1231
      // The field stores the length of a captured variable-length array.
1232
      // These captures don't have initialization expressions; instead we
1233
      // get the length from the VLAType size expression.
1234
2
      Expr *SizeExpr = FieldForCapture->getCapturedVLAType()->getSizeExpr();
1235
2
      InitVal = State->getSVal(SizeExpr, LocCtxt);
1236
2
    }
1237
1238
250
    State = State->bindLoc(FieldLoc, InitVal, LocCtxt);
1239
250
  }
1240
1241
  // Decay the Loc into an RValue, because there might be a
1242
  // MaterializeTemporaryExpr node above this one which expects the bound value
1243
  // to be an RValue.
1244
539
  SVal LambdaRVal = State->getSVal(R);
1245
1246
539
  ExplodedNodeSet Tmp;
1247
539
  StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx);
1248
  // FIXME: is this the right program point kind?
1249
539
  Bldr.generateNode(LE, Pred,
1250
539
                    State->BindExpr(LE, LocCtxt, LambdaRVal),
1251
539
                    nullptr, ProgramPoint::PostLValueKind);
1252
1253
  // FIXME: Move all post/pre visits to ::Visit().
1254
539
  getCheckerManager().runCheckersForPostStmt(Dst, Tmp, LE, *this);
1255
539
}