File indexing completed on 2026-05-10 08:37:07
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLEVENT_H
0016 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLEVENT_H
0017
0018 #include "clang/AST/Decl.h"
0019 #include "clang/AST/DeclBase.h"
0020 #include "clang/AST/DeclCXX.h"
0021 #include "clang/AST/DeclObjC.h"
0022 #include "clang/AST/Expr.h"
0023 #include "clang/AST/ExprCXX.h"
0024 #include "clang/AST/ExprObjC.h"
0025 #include "clang/AST/Stmt.h"
0026 #include "clang/AST/Type.h"
0027 #include "clang/Basic/IdentifierTable.h"
0028 #include "clang/Basic/LLVM.h"
0029 #include "clang/Basic/SourceLocation.h"
0030 #include "clang/Basic/SourceManager.h"
0031 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
0032 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
0033 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
0034 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
0035 #include "llvm/ADT/ArrayRef.h"
0036 #include "llvm/ADT/IntrusiveRefCntPtr.h"
0037 #include "llvm/ADT/PointerIntPair.h"
0038 #include "llvm/ADT/PointerUnion.h"
0039 #include "llvm/ADT/STLExtras.h"
0040 #include "llvm/ADT/SmallVector.h"
0041 #include "llvm/ADT/StringRef.h"
0042 #include "llvm/ADT/iterator_range.h"
0043 #include "llvm/Support/Allocator.h"
0044 #include "llvm/Support/Casting.h"
0045 #include "llvm/Support/ErrorHandling.h"
0046 #include <cassert>
0047 #include <limits>
0048 #include <optional>
0049 #include <utility>
0050
0051 namespace clang {
0052
0053 class LocationContext;
0054 class ProgramPoint;
0055 class ProgramPointTag;
0056 class StackFrameContext;
0057
0058 namespace ento {
0059
0060 enum CallEventKind {
0061 CE_Function,
0062 CE_CXXStaticOperator,
0063 CE_CXXMember,
0064 CE_CXXMemberOperator,
0065 CE_CXXDestructor,
0066 CE_BEG_CXX_INSTANCE_CALLS = CE_CXXMember,
0067 CE_END_CXX_INSTANCE_CALLS = CE_CXXDestructor,
0068 CE_CXXConstructor,
0069 CE_CXXInheritedConstructor,
0070 CE_BEG_CXX_CONSTRUCTOR_CALLS = CE_CXXConstructor,
0071 CE_END_CXX_CONSTRUCTOR_CALLS = CE_CXXInheritedConstructor,
0072 CE_CXXAllocator,
0073 CE_CXXDeallocator,
0074 CE_BEG_FUNCTION_CALLS = CE_Function,
0075 CE_END_FUNCTION_CALLS = CE_CXXDeallocator,
0076 CE_Block,
0077 CE_ObjCMessage
0078 };
0079
0080 class CallEvent;
0081
0082 template <typename T = CallEvent>
0083 class CallEventRef : public IntrusiveRefCntPtr<const T> {
0084 public:
0085 CallEventRef(const T *Call) : IntrusiveRefCntPtr<const T>(Call) {}
0086 CallEventRef(const CallEventRef &Orig) : IntrusiveRefCntPtr<const T>(Orig) {}
0087
0088
0089
0090 CallEventRef &operator=(const CallEventRef &) = delete;
0091
0092 CallEventRef<T> cloneWithState(ProgramStateRef State) const {
0093 return this->get()->template cloneWithState<T>(State);
0094 }
0095
0096
0097
0098 template <typename SuperT> operator CallEventRef<SuperT>() const {
0099 return this->get();
0100 }
0101 };
0102
0103
0104
0105
0106
0107
0108
0109
0110 class RuntimeDefinition {
0111
0112
0113 const Decl *D = nullptr;
0114
0115
0116
0117
0118
0119 const MemRegion *R = nullptr;
0120
0121
0122
0123 const bool Foreign = false;
0124
0125 public:
0126 RuntimeDefinition() = default;
0127 RuntimeDefinition(const Decl *InD) : D(InD) {}
0128 RuntimeDefinition(const Decl *InD, bool Foreign) : D(InD), Foreign(Foreign) {}
0129 RuntimeDefinition(const Decl *InD, const MemRegion *InR) : D(InD), R(InR) {}
0130
0131 const Decl *getDecl() { return D; }
0132 bool isForeign() const { return Foreign; }
0133
0134
0135
0136
0137 bool mayHaveOtherDefinitions() { return R != nullptr; }
0138
0139
0140
0141 const MemRegion *getDispatchRegion() { return R; }
0142 };
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153 class CallEvent {
0154 public:
0155 using Kind = CallEventKind;
0156
0157 private:
0158 ProgramStateRef State;
0159 const LocationContext *LCtx;
0160 llvm::PointerUnion<const Expr *, const Decl *> Origin;
0161 CFGBlock::ConstCFGElementRef ElemRef = {nullptr, 0};
0162 mutable std::optional<bool> Foreign;
0163
0164 protected:
0165
0166 const void *Data;
0167
0168
0169
0170
0171 SourceLocation Location;
0172
0173 private:
0174 template <typename T> friend struct llvm::IntrusiveRefCntPtrInfo;
0175
0176 mutable unsigned RefCount = 0;
0177
0178 void Retain() const { ++RefCount; }
0179 void Release() const;
0180
0181 protected:
0182 friend class CallEventManager;
0183
0184 CallEvent(const Expr *E, ProgramStateRef state, const LocationContext *lctx,
0185 CFGBlock::ConstCFGElementRef ElemRef)
0186 : State(std::move(state)), LCtx(lctx), Origin(E), ElemRef(ElemRef) {}
0187
0188 CallEvent(const Decl *D, ProgramStateRef state, const LocationContext *lctx,
0189 CFGBlock::ConstCFGElementRef ElemRef)
0190 : State(std::move(state)), LCtx(lctx), Origin(D), ElemRef(ElemRef) {}
0191
0192
0193 CallEvent(const CallEvent &Original)
0194 : State(Original.State), LCtx(Original.LCtx), Origin(Original.Origin),
0195 ElemRef(Original.ElemRef), Data(Original.Data),
0196 Location(Original.Location) {}
0197
0198
0199 virtual void cloneTo(void *Dest) const = 0;
0200
0201
0202 SVal getSVal(const Stmt *S) const {
0203 return getState()->getSVal(S, getLocationContext());
0204 }
0205
0206 using ValueList = SmallVectorImpl<SVal>;
0207
0208
0209
0210 virtual void
0211 getExtraInvalidatedValues(ValueList &Values,
0212 RegionAndSymbolInvalidationTraits *ETraits) const {}
0213
0214 public:
0215 CallEvent &operator=(const CallEvent &) = delete;
0216 virtual ~CallEvent() = default;
0217
0218
0219 virtual Kind getKind() const = 0;
0220 virtual StringRef getKindAsString() const = 0;
0221
0222
0223
0224 virtual const Decl *getDecl() const {
0225 return Origin.dyn_cast<const Decl *>();
0226 }
0227
0228 bool isForeign() const {
0229 assert(Foreign && "Foreign must be set before querying");
0230 return *Foreign;
0231 }
0232 void setForeign(bool B) const { Foreign = B; }
0233
0234
0235 const ProgramStateRef &getState() const { return State; }
0236
0237
0238 const LocationContext *getLocationContext() const { return LCtx; }
0239
0240 const CFGBlock::ConstCFGElementRef &getCFGElementRef() const {
0241 return ElemRef;
0242 }
0243
0244
0245
0246 virtual RuntimeDefinition getRuntimeDefinition() const = 0;
0247
0248
0249
0250 virtual const Expr *getOriginExpr() const {
0251 return Origin.dyn_cast<const Expr *>();
0252 }
0253
0254
0255
0256
0257
0258
0259 virtual unsigned getNumArgs() const = 0;
0260
0261
0262 bool isInSystemHeader() const {
0263 const Decl *D = getDecl();
0264 if (!D)
0265 return false;
0266
0267 SourceLocation Loc = D->getLocation();
0268 if (Loc.isValid()) {
0269 const SourceManager &SM =
0270 getState()->getStateManager().getContext().getSourceManager();
0271 return SM.isInSystemHeader(D->getLocation());
0272 }
0273
0274
0275
0276 if (const auto *FD = dyn_cast<FunctionDecl>(D))
0277 return FD->isOverloadedOperator() && FD->isImplicit() && FD->isGlobal();
0278
0279 return false;
0280 }
0281
0282
0283
0284 virtual SourceRange getSourceRange() const {
0285 return getOriginExpr()->getSourceRange();
0286 }
0287
0288
0289 virtual SVal getArgSVal(unsigned Index) const;
0290
0291
0292
0293 virtual const Expr *getArgExpr(unsigned Index) const { return nullptr; }
0294
0295
0296
0297
0298 virtual SourceRange getArgSourceRange(unsigned Index) const;
0299
0300
0301 QualType getResultType() const;
0302
0303
0304
0305
0306
0307 SVal getReturnValue() const;
0308
0309
0310
0311 bool hasNonNullArgumentsWithType(bool (*Condition)(QualType)) const;
0312
0313
0314 bool hasNonZeroCallbackArg() const;
0315
0316
0317 bool hasVoidPointerToNonConstArg() const;
0318
0319
0320
0321
0322
0323
0324 virtual bool argumentsMayEscape() const { return hasNonZeroCallbackArg(); }
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342 bool isGlobalCFunction(StringRef SpecificName = StringRef()) const;
0343
0344
0345
0346
0347
0348
0349
0350
0351 const IdentifierInfo *getCalleeIdentifier() const {
0352 const auto *ND = dyn_cast_or_null<NamedDecl>(getDecl());
0353 if (!ND)
0354 return nullptr;
0355 return ND->getIdentifier();
0356 }
0357
0358
0359 ProgramPoint getProgramPoint(bool IsPreVisit = false,
0360 const ProgramPointTag *Tag = nullptr) const;
0361
0362
0363
0364
0365
0366 ProgramStateRef invalidateRegions(unsigned BlockCount,
0367 ProgramStateRef Orig = nullptr) const;
0368
0369 using FrameBindingTy = std::pair<SVal, SVal>;
0370 using BindingsTy = SmallVectorImpl<FrameBindingTy>;
0371
0372
0373
0374 virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
0375 BindingsTy &Bindings) const = 0;
0376
0377
0378 template <typename T>
0379 CallEventRef<T> cloneWithState(ProgramStateRef NewState) const;
0380
0381
0382 CallEventRef<> cloneWithState(ProgramStateRef NewState) const {
0383 return cloneWithState<CallEvent>(NewState);
0384 }
0385
0386
0387
0388 static bool isCallStmt(const Stmt *S);
0389
0390
0391
0392
0393 static QualType getDeclaredResultType(const Decl *D);
0394
0395
0396
0397
0398 static bool isVariadic(const Decl *D);
0399
0400
0401
0402 AnalysisDeclContext *getCalleeAnalysisDeclContext() const;
0403
0404
0405
0406
0407
0408 const StackFrameContext *getCalleeStackFrame(unsigned BlockCount) const;
0409
0410
0411
0412
0413 const ParamVarRegion *getParameterLocation(unsigned Index,
0414 unsigned BlockCount) const;
0415
0416
0417
0418
0419
0420
0421
0422 bool isArgumentConstructedDirectly(unsigned Index) const {
0423
0424 return ExprEngine::getObjectUnderConstruction(
0425 getState(), {getOriginExpr(), Index}, getLocationContext())
0426 .has_value();
0427 }
0428
0429
0430
0431
0432
0433 virtual std::optional<unsigned>
0434 getAdjustedParameterIndex(unsigned ASTArgumentIndex) const {
0435 return ASTArgumentIndex;
0436 }
0437
0438
0439
0440
0441 virtual unsigned getASTArgumentIndex(unsigned CallArgumentIndex) const {
0442 return CallArgumentIndex;
0443 }
0444
0445
0446
0447
0448 const ConstructionContext *getConstructionContext() const;
0449
0450
0451
0452 std::optional<SVal> getReturnValueUnderConstruction() const;
0453
0454
0455 const CallEventRef<> getCaller() const;
0456
0457
0458
0459
0460 bool isCalledFromSystemHeader() const;
0461
0462
0463 private:
0464 struct GetTypeFn {
0465 QualType operator()(ParmVarDecl *PD) const { return PD->getType(); }
0466 };
0467
0468 public:
0469
0470
0471
0472
0473
0474 virtual ArrayRef<ParmVarDecl *> parameters() const = 0;
0475
0476 using param_type_iterator =
0477 llvm::mapped_iterator<ArrayRef<ParmVarDecl *>::iterator, GetTypeFn>;
0478
0479
0480
0481
0482
0483
0484 param_type_iterator param_type_begin() const {
0485 return llvm::map_iterator(parameters().begin(), GetTypeFn());
0486 }
0487
0488 param_type_iterator param_type_end() const {
0489 return llvm::map_iterator(parameters().end(), GetTypeFn());
0490 }
0491
0492
0493 void dump(raw_ostream &Out) const;
0494 void dump() const;
0495 };
0496
0497
0498
0499 class AnyFunctionCall : public CallEvent {
0500 protected:
0501 AnyFunctionCall(const Expr *E, ProgramStateRef St,
0502 const LocationContext *LCtx,
0503 CFGBlock::ConstCFGElementRef ElemRef)
0504 : CallEvent(E, St, LCtx, ElemRef) {}
0505 AnyFunctionCall(const Decl *D, ProgramStateRef St,
0506 const LocationContext *LCtx,
0507 CFGBlock::ConstCFGElementRef ElemRef)
0508 : CallEvent(D, St, LCtx, ElemRef) {}
0509 AnyFunctionCall(const AnyFunctionCall &Other) = default;
0510
0511 public:
0512
0513
0514 const FunctionDecl *getDecl() const override {
0515 return cast<FunctionDecl>(CallEvent::getDecl());
0516 }
0517
0518 RuntimeDefinition getRuntimeDefinition() const override;
0519
0520 bool argumentsMayEscape() const override;
0521
0522 void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
0523 BindingsTy &Bindings) const override;
0524
0525 ArrayRef<ParmVarDecl *> parameters() const override;
0526
0527 static bool classof(const CallEvent *CA) {
0528 return CA->getKind() >= CE_BEG_FUNCTION_CALLS &&
0529 CA->getKind() <= CE_END_FUNCTION_CALLS;
0530 }
0531 };
0532
0533
0534
0535
0536 class SimpleFunctionCall : public AnyFunctionCall {
0537 friend class CallEventManager;
0538
0539 protected:
0540 SimpleFunctionCall(const CallExpr *CE, ProgramStateRef St,
0541 const LocationContext *LCtx,
0542 CFGBlock::ConstCFGElementRef ElemRef)
0543 : AnyFunctionCall(CE, St, LCtx, ElemRef) {}
0544 SimpleFunctionCall(const SimpleFunctionCall &Other) = default;
0545
0546 void cloneTo(void *Dest) const override {
0547 new (Dest) SimpleFunctionCall(*this);
0548 }
0549
0550 public:
0551 const CallExpr *getOriginExpr() const override {
0552 return cast<CallExpr>(AnyFunctionCall::getOriginExpr());
0553 }
0554
0555 const FunctionDecl *getDecl() const override;
0556
0557 unsigned getNumArgs() const override { return getOriginExpr()->getNumArgs(); }
0558
0559 const Expr *getArgExpr(unsigned Index) const override {
0560 return getOriginExpr()->getArg(Index);
0561 }
0562
0563 Kind getKind() const override { return CE_Function; }
0564 StringRef getKindAsString() const override { return "SimpleFunctionCall"; }
0565
0566 static bool classof(const CallEvent *CA) {
0567 return CA->getKind() == CE_Function;
0568 }
0569 };
0570
0571
0572
0573
0574 class BlockCall : public CallEvent {
0575 friend class CallEventManager;
0576
0577 protected:
0578 BlockCall(const CallExpr *CE, ProgramStateRef St, const LocationContext *LCtx,
0579 CFGBlock::ConstCFGElementRef ElemRef)
0580 : CallEvent(CE, St, LCtx, ElemRef) {}
0581 BlockCall(const BlockCall &Other) = default;
0582
0583 void cloneTo(void *Dest) const override { new (Dest) BlockCall(*this); }
0584
0585 void getExtraInvalidatedValues(
0586 ValueList &Values,
0587 RegionAndSymbolInvalidationTraits *ETraits) const override;
0588
0589 public:
0590 const CallExpr *getOriginExpr() const override {
0591 return cast<CallExpr>(CallEvent::getOriginExpr());
0592 }
0593
0594 unsigned getNumArgs() const override { return getOriginExpr()->getNumArgs(); }
0595
0596 const Expr *getArgExpr(unsigned Index) const override {
0597 return getOriginExpr()->getArg(Index);
0598 }
0599
0600
0601
0602
0603 const BlockDataRegion *getBlockRegion() const;
0604
0605 const BlockDecl *getDecl() const override {
0606 const BlockDataRegion *BR = getBlockRegion();
0607 if (!BR)
0608 return nullptr;
0609 return BR->getDecl();
0610 }
0611
0612 bool isConversionFromLambda() const {
0613 const BlockDecl *BD = getDecl();
0614 if (!BD)
0615 return false;
0616
0617 return BD->isConversionFromLambda();
0618 }
0619
0620
0621
0622 const VarRegion *getRegionStoringCapturedLambda() const {
0623 assert(isConversionFromLambda());
0624 const BlockDataRegion *BR = getBlockRegion();
0625 assert(BR && "Block converted from lambda must have a block region");
0626
0627 auto ReferencedVars = BR->referenced_vars();
0628 assert(!ReferencedVars.empty());
0629 return ReferencedVars.begin().getCapturedRegion();
0630 }
0631
0632 RuntimeDefinition getRuntimeDefinition() const override {
0633 if (!isConversionFromLambda())
0634 return RuntimeDefinition(getDecl());
0635
0636
0637
0638
0639
0640
0641
0642
0643
0644
0645
0646
0647
0648
0649
0650
0651
0652
0653
0654
0655 const VarDecl *LambdaVD = getRegionStoringCapturedLambda()->getDecl();
0656 const CXXRecordDecl *LambdaDecl = LambdaVD->getType()->getAsCXXRecordDecl();
0657 CXXMethodDecl *LambdaCallOperator = LambdaDecl->getLambdaCallOperator();
0658
0659 return RuntimeDefinition(LambdaCallOperator);
0660 }
0661
0662 bool argumentsMayEscape() const override { return true; }
0663
0664 void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
0665 BindingsTy &Bindings) const override;
0666
0667 ArrayRef<ParmVarDecl *> parameters() const override;
0668
0669 Kind getKind() const override { return CE_Block; }
0670 StringRef getKindAsString() const override { return "BlockCall"; }
0671
0672 static bool classof(const CallEvent *CA) { return CA->getKind() == CE_Block; }
0673 };
0674
0675
0676
0677 class CXXInstanceCall : public AnyFunctionCall {
0678 protected:
0679 CXXInstanceCall(const CallExpr *CE, ProgramStateRef St,
0680 const LocationContext *LCtx,
0681 CFGBlock::ConstCFGElementRef ElemRef)
0682 : AnyFunctionCall(CE, St, LCtx, ElemRef) {}
0683 CXXInstanceCall(const FunctionDecl *D, ProgramStateRef St,
0684 const LocationContext *LCtx,
0685 CFGBlock::ConstCFGElementRef ElemRef)
0686 : AnyFunctionCall(D, St, LCtx, ElemRef) {}
0687 CXXInstanceCall(const CXXInstanceCall &Other) = default;
0688
0689 void getExtraInvalidatedValues(
0690 ValueList &Values,
0691 RegionAndSymbolInvalidationTraits *ETraits) const override;
0692
0693
0694
0695
0696 std::pair<const CXXRecordDecl *, bool> getDeclForDynamicType() const;
0697
0698 public:
0699
0700 virtual const Expr *getCXXThisExpr() const { return nullptr; }
0701
0702
0703 virtual SVal getCXXThisVal() const;
0704
0705 const FunctionDecl *getDecl() const override;
0706
0707 RuntimeDefinition getRuntimeDefinition() const override;
0708
0709 void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
0710 BindingsTy &Bindings) const override;
0711
0712 static bool classof(const CallEvent *CA) {
0713 return CA->getKind() >= CE_BEG_CXX_INSTANCE_CALLS &&
0714 CA->getKind() <= CE_END_CXX_INSTANCE_CALLS;
0715 }
0716 };
0717
0718
0719
0720
0721
0722
0723
0724
0725
0726
0727
0728
0729
0730
0731
0732
0733
0734 class CXXStaticOperatorCall : public SimpleFunctionCall {
0735 friend class CallEventManager;
0736
0737 protected:
0738 CXXStaticOperatorCall(const CXXOperatorCallExpr *CE, ProgramStateRef St,
0739 const LocationContext *LCtx,
0740 CFGBlock::ConstCFGElementRef ElemRef)
0741 : SimpleFunctionCall(CE, St, LCtx, ElemRef) {}
0742 CXXStaticOperatorCall(const CXXStaticOperatorCall &Other) = default;
0743
0744 void cloneTo(void *Dest) const override {
0745 new (Dest) CXXStaticOperatorCall(*this);
0746 }
0747
0748 public:
0749 const CXXOperatorCallExpr *getOriginExpr() const override {
0750 return cast<CXXOperatorCallExpr>(SimpleFunctionCall::getOriginExpr());
0751 }
0752
0753 unsigned getNumArgs() const override {
0754
0755 assert(getOriginExpr()->getNumArgs() > 0);
0756 return getOriginExpr()->getNumArgs() - 1;
0757 }
0758
0759 const Expr *getArgExpr(unsigned Index) const override {
0760
0761 return getOriginExpr()->getArg(Index + 1);
0762 }
0763
0764 std::optional<unsigned>
0765 getAdjustedParameterIndex(unsigned ASTArgumentIndex) const override {
0766
0767 if (ASTArgumentIndex == 0)
0768 return std::nullopt;
0769 return ASTArgumentIndex - 1;
0770 }
0771
0772 unsigned getASTArgumentIndex(unsigned CallArgumentIndex) const override {
0773
0774 return CallArgumentIndex + 1;
0775 }
0776
0777 OverloadedOperatorKind getOverloadedOperator() const {
0778 return getOriginExpr()->getOperator();
0779 }
0780
0781 Kind getKind() const override { return CE_CXXStaticOperator; }
0782 StringRef getKindAsString() const override { return "CXXStaticOperatorCall"; }
0783
0784 static bool classof(const CallEvent *CA) {
0785 return CA->getKind() == CE_CXXStaticOperator;
0786 }
0787 };
0788
0789
0790
0791
0792 class CXXMemberCall : public CXXInstanceCall {
0793 friend class CallEventManager;
0794
0795 protected:
0796 CXXMemberCall(const CXXMemberCallExpr *CE, ProgramStateRef St,
0797 const LocationContext *LCtx,
0798 CFGBlock::ConstCFGElementRef ElemRef)
0799 : CXXInstanceCall(CE, St, LCtx, ElemRef) {}
0800 CXXMemberCall(const CXXMemberCall &Other) = default;
0801
0802 void cloneTo(void *Dest) const override { new (Dest) CXXMemberCall(*this); }
0803
0804 public:
0805 const CXXMemberCallExpr *getOriginExpr() const override {
0806 return cast<CXXMemberCallExpr>(CXXInstanceCall::getOriginExpr());
0807 }
0808
0809 unsigned getNumArgs() const override {
0810 if (const CallExpr *CE = getOriginExpr())
0811 return CE->getNumArgs();
0812 return 0;
0813 }
0814
0815 const Expr *getArgExpr(unsigned Index) const override {
0816 return getOriginExpr()->getArg(Index);
0817 }
0818
0819 const Expr *getCXXThisExpr() const override;
0820
0821 RuntimeDefinition getRuntimeDefinition() const override;
0822
0823 Kind getKind() const override { return CE_CXXMember; }
0824 StringRef getKindAsString() const override { return "CXXMemberCall"; }
0825
0826 static bool classof(const CallEvent *CA) {
0827 return CA->getKind() == CE_CXXMember;
0828 }
0829 };
0830
0831
0832
0833
0834
0835 class CXXMemberOperatorCall : public CXXInstanceCall {
0836 friend class CallEventManager;
0837
0838 protected:
0839 CXXMemberOperatorCall(const CXXOperatorCallExpr *CE, ProgramStateRef St,
0840 const LocationContext *LCtx,
0841 CFGBlock::ConstCFGElementRef ElemRef)
0842 : CXXInstanceCall(CE, St, LCtx, ElemRef) {}
0843 CXXMemberOperatorCall(const CXXMemberOperatorCall &Other) = default;
0844
0845 void cloneTo(void *Dest) const override {
0846 new (Dest) CXXMemberOperatorCall(*this);
0847 }
0848
0849 public:
0850 const CXXOperatorCallExpr *getOriginExpr() const override {
0851 return cast<CXXOperatorCallExpr>(CXXInstanceCall::getOriginExpr());
0852 }
0853
0854 unsigned getNumArgs() const override {
0855 return getOriginExpr()->getNumArgs() - 1;
0856 }
0857
0858 const Expr *getArgExpr(unsigned Index) const override {
0859 return getOriginExpr()->getArg(Index + 1);
0860 }
0861
0862 const Expr *getCXXThisExpr() const override;
0863
0864 Kind getKind() const override { return CE_CXXMemberOperator; }
0865 StringRef getKindAsString() const override { return "CXXMemberOperatorCall"; }
0866
0867 static bool classof(const CallEvent *CA) {
0868 return CA->getKind() == CE_CXXMemberOperator;
0869 }
0870
0871 std::optional<unsigned>
0872 getAdjustedParameterIndex(unsigned ASTArgumentIndex) const override {
0873
0874
0875 return (ASTArgumentIndex > 0)
0876 ? std::optional<unsigned>(ASTArgumentIndex - 1)
0877 : std::nullopt;
0878 }
0879
0880 unsigned getASTArgumentIndex(unsigned CallArgumentIndex) const override {
0881
0882
0883 return CallArgumentIndex + 1;
0884 }
0885
0886 OverloadedOperatorKind getOverloadedOperator() const {
0887 return getOriginExpr()->getOperator();
0888 }
0889 };
0890
0891
0892
0893
0894
0895 class CXXDestructorCall : public CXXInstanceCall {
0896 friend class CallEventManager;
0897
0898 protected:
0899 using DtorDataTy = llvm::PointerIntPair<const MemRegion *, 1, bool>;
0900
0901
0902
0903
0904
0905
0906
0907
0908
0909
0910
0911
0912
0913
0914 CXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger,
0915 const MemRegion *Target, bool IsBaseDestructor,
0916 ProgramStateRef St, const LocationContext *LCtx,
0917 CFGBlock::ConstCFGElementRef ElemRef)
0918 : CXXInstanceCall(DD, St, LCtx, ElemRef) {
0919 Data = DtorDataTy(Target, IsBaseDestructor).getOpaqueValue();
0920 Location = Trigger->getEndLoc();
0921 }
0922
0923 CXXDestructorCall(const CXXDestructorCall &Other) = default;
0924
0925 void cloneTo(void *Dest) const override {
0926 new (Dest) CXXDestructorCall(*this);
0927 }
0928
0929 public:
0930 SourceRange getSourceRange() const override { return Location; }
0931 unsigned getNumArgs() const override { return 0; }
0932
0933 RuntimeDefinition getRuntimeDefinition() const override;
0934
0935
0936 SVal getCXXThisVal() const override;
0937
0938
0939 bool isBaseDestructor() const {
0940 return DtorDataTy::getFromOpaqueValue(Data).getInt();
0941 }
0942
0943 Kind getKind() const override { return CE_CXXDestructor; }
0944 StringRef getKindAsString() const override { return "CXXDestructorCall"; }
0945
0946 static bool classof(const CallEvent *CA) {
0947 return CA->getKind() == CE_CXXDestructor;
0948 }
0949 };
0950
0951
0952
0953 class AnyCXXConstructorCall : public AnyFunctionCall {
0954 protected:
0955 AnyCXXConstructorCall(const Expr *E, const MemRegion *Target,
0956 ProgramStateRef St, const LocationContext *LCtx,
0957 CFGBlock::ConstCFGElementRef ElemRef)
0958 : AnyFunctionCall(E, St, LCtx, ElemRef) {
0959 assert(E && (isa<CXXConstructExpr>(E) || isa<CXXInheritedCtorInitExpr>(E)));
0960
0961 Data = Target;
0962 }
0963
0964 void getExtraInvalidatedValues(
0965 ValueList &Values,
0966 RegionAndSymbolInvalidationTraits *ETraits) const override;
0967
0968 void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
0969 BindingsTy &Bindings) const override;
0970
0971 public:
0972
0973 SVal getCXXThisVal() const;
0974
0975 static bool classof(const CallEvent *Call) {
0976 return Call->getKind() >= CE_BEG_CXX_CONSTRUCTOR_CALLS &&
0977 Call->getKind() <= CE_END_CXX_CONSTRUCTOR_CALLS;
0978 }
0979 };
0980
0981
0982
0983
0984 class CXXConstructorCall : public AnyCXXConstructorCall {
0985 friend class CallEventManager;
0986
0987 protected:
0988
0989
0990
0991
0992
0993
0994
0995
0996
0997
0998
0999 CXXConstructorCall(const CXXConstructExpr *CE, const MemRegion *Target,
1000 ProgramStateRef St, const LocationContext *LCtx,
1001 CFGBlock::ConstCFGElementRef ElemRef)
1002 : AnyCXXConstructorCall(CE, Target, St, LCtx, ElemRef) {}
1003
1004 CXXConstructorCall(const CXXConstructorCall &Other) = default;
1005
1006 void cloneTo(void *Dest) const override {
1007 new (Dest) CXXConstructorCall(*this);
1008 }
1009
1010 public:
1011 const CXXConstructExpr *getOriginExpr() const override {
1012 return cast<CXXConstructExpr>(AnyFunctionCall::getOriginExpr());
1013 }
1014
1015 const CXXConstructorDecl *getDecl() const override {
1016 return getOriginExpr()->getConstructor();
1017 }
1018
1019 unsigned getNumArgs() const override { return getOriginExpr()->getNumArgs(); }
1020
1021 const Expr *getArgExpr(unsigned Index) const override {
1022 return getOriginExpr()->getArg(Index);
1023 }
1024
1025 Kind getKind() const override { return CE_CXXConstructor; }
1026 StringRef getKindAsString() const override { return "CXXConstructorCall"; }
1027
1028 static bool classof(const CallEvent *CA) {
1029 return CA->getKind() == CE_CXXConstructor;
1030 }
1031 };
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053 class CXXInheritedConstructorCall : public AnyCXXConstructorCall {
1054 friend class CallEventManager;
1055
1056 protected:
1057 CXXInheritedConstructorCall(const CXXInheritedCtorInitExpr *CE,
1058 const MemRegion *Target, ProgramStateRef St,
1059 const LocationContext *LCtx,
1060 CFGBlock::ConstCFGElementRef ElemRef)
1061 : AnyCXXConstructorCall(CE, Target, St, LCtx, ElemRef) {}
1062
1063 CXXInheritedConstructorCall(const CXXInheritedConstructorCall &Other) =
1064 default;
1065
1066 void cloneTo(void *Dest) const override {
1067 new (Dest) CXXInheritedConstructorCall(*this);
1068 }
1069
1070 public:
1071 const CXXInheritedCtorInitExpr *getOriginExpr() const override {
1072 return cast<CXXInheritedCtorInitExpr>(AnyFunctionCall::getOriginExpr());
1073 }
1074
1075 const CXXConstructorDecl *getDecl() const override {
1076 return getOriginExpr()->getConstructor();
1077 }
1078
1079
1080
1081 const StackFrameContext *getInheritingStackFrame() const;
1082
1083
1084
1085
1086 const CXXConstructExpr *getInheritingConstructor() const {
1087 return cast<CXXConstructExpr>(getInheritingStackFrame()->getCallSite());
1088 }
1089
1090 unsigned getNumArgs() const override {
1091 return getInheritingConstructor()->getNumArgs();
1092 }
1093
1094 const Expr *getArgExpr(unsigned Index) const override {
1095 return getInheritingConstructor()->getArg(Index);
1096 }
1097
1098 SVal getArgSVal(unsigned Index) const override {
1099 return getState()->getSVal(
1100 getArgExpr(Index),
1101 getInheritingStackFrame()->getParent()->getStackFrame());
1102 }
1103
1104 Kind getKind() const override { return CE_CXXInheritedConstructor; }
1105 StringRef getKindAsString() const override {
1106 return "CXXInheritedConstructorCall";
1107 }
1108
1109 static bool classof(const CallEvent *CA) {
1110 return CA->getKind() == CE_CXXInheritedConstructor;
1111 }
1112 };
1113
1114
1115
1116
1117 class CXXAllocatorCall : public AnyFunctionCall {
1118 friend class CallEventManager;
1119
1120 protected:
1121 CXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef St,
1122 const LocationContext *LCtx,
1123 CFGBlock::ConstCFGElementRef ElemRef)
1124 : AnyFunctionCall(E, St, LCtx, ElemRef) {}
1125 CXXAllocatorCall(const CXXAllocatorCall &Other) = default;
1126
1127 void cloneTo(void *Dest) const override {
1128 new (Dest) CXXAllocatorCall(*this);
1129 }
1130
1131 public:
1132 const CXXNewExpr *getOriginExpr() const override {
1133 return cast<CXXNewExpr>(AnyFunctionCall::getOriginExpr());
1134 }
1135
1136 const FunctionDecl *getDecl() const override {
1137 return getOriginExpr()->getOperatorNew();
1138 }
1139
1140 SVal getObjectUnderConstruction() const {
1141 return *ExprEngine::getObjectUnderConstruction(getState(), getOriginExpr(),
1142 getLocationContext());
1143 }
1144
1145
1146
1147
1148 unsigned getNumImplicitArgs() const {
1149 return getOriginExpr()->passAlignment() ? 2 : 1;
1150 }
1151
1152 unsigned getNumArgs() const override {
1153 return getOriginExpr()->getNumPlacementArgs() + getNumImplicitArgs();
1154 }
1155
1156 bool isArray() const { return getOriginExpr()->isArray(); }
1157
1158 std::optional<const clang::Expr *> getArraySizeExpr() const {
1159 return getOriginExpr()->getArraySize();
1160 }
1161
1162 SVal getArraySizeVal() const {
1163 assert(isArray() && "The allocator call doesn't allocate and array!");
1164
1165 return getState()->getSVal(*getArraySizeExpr(), getLocationContext());
1166 }
1167
1168 const Expr *getArgExpr(unsigned Index) const override {
1169
1170 if (Index < getNumImplicitArgs())
1171 return nullptr;
1172 return getOriginExpr()->getPlacementArg(Index - getNumImplicitArgs());
1173 }
1174
1175
1176
1177
1178
1179 const Expr *getPlacementArgExpr(unsigned Index) const {
1180 return getOriginExpr()->getPlacementArg(Index);
1181 }
1182
1183 Kind getKind() const override { return CE_CXXAllocator; }
1184 StringRef getKindAsString() const override { return "CXXAllocatorCall"; }
1185
1186 static bool classof(const CallEvent *CE) {
1187 return CE->getKind() == CE_CXXAllocator;
1188 }
1189 };
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201 class CXXDeallocatorCall : public AnyFunctionCall {
1202 friend class CallEventManager;
1203
1204 protected:
1205 CXXDeallocatorCall(const CXXDeleteExpr *E, ProgramStateRef St,
1206 const LocationContext *LCtx,
1207 CFGBlock::ConstCFGElementRef ElemRef)
1208 : AnyFunctionCall(E, St, LCtx, ElemRef) {}
1209 CXXDeallocatorCall(const CXXDeallocatorCall &Other) = default;
1210
1211 void cloneTo(void *Dest) const override {
1212 new (Dest) CXXDeallocatorCall(*this);
1213 }
1214
1215 public:
1216 const CXXDeleteExpr *getOriginExpr() const override {
1217 return cast<CXXDeleteExpr>(AnyFunctionCall::getOriginExpr());
1218 }
1219
1220 const FunctionDecl *getDecl() const override {
1221 return getOriginExpr()->getOperatorDelete();
1222 }
1223
1224 unsigned getNumArgs() const override { return getDecl()->getNumParams(); }
1225
1226 const Expr *getArgExpr(unsigned Index) const override {
1227
1228 return getOriginExpr()->getArgument();
1229 }
1230
1231 Kind getKind() const override { return CE_CXXDeallocator; }
1232 StringRef getKindAsString() const override { return "CXXDeallocatorCall"; }
1233
1234 static bool classof(const CallEvent *CE) {
1235 return CE->getKind() == CE_CXXDeallocator;
1236 }
1237 };
1238
1239
1240
1241
1242
1243 enum ObjCMessageKind { OCM_PropertyAccess, OCM_Subscript, OCM_Message };
1244
1245
1246
1247
1248 class ObjCMethodCall : public CallEvent {
1249 friend class CallEventManager;
1250
1251 const PseudoObjectExpr *getContainingPseudoObjectExpr() const;
1252
1253 protected:
1254 ObjCMethodCall(const ObjCMessageExpr *Msg, ProgramStateRef St,
1255 const LocationContext *LCtx,
1256 CFGBlock::ConstCFGElementRef ElemRef)
1257 : CallEvent(Msg, St, LCtx, ElemRef) {
1258 Data = nullptr;
1259 }
1260
1261 ObjCMethodCall(const ObjCMethodCall &Other) = default;
1262
1263 void cloneTo(void *Dest) const override { new (Dest) ObjCMethodCall(*this); }
1264
1265 void getExtraInvalidatedValues(
1266 ValueList &Values,
1267 RegionAndSymbolInvalidationTraits *ETraits) const override;
1268
1269
1270 virtual bool canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl,
1271 Selector Sel) const;
1272
1273 public:
1274 const ObjCMessageExpr *getOriginExpr() const override {
1275 return cast<ObjCMessageExpr>(CallEvent::getOriginExpr());
1276 }
1277
1278 const ObjCMethodDecl *getDecl() const override {
1279 return getOriginExpr()->getMethodDecl();
1280 }
1281
1282 unsigned getNumArgs() const override { return getOriginExpr()->getNumArgs(); }
1283
1284 const Expr *getArgExpr(unsigned Index) const override {
1285 return getOriginExpr()->getArg(Index);
1286 }
1287
1288 bool isInstanceMessage() const {
1289 return getOriginExpr()->isInstanceMessage();
1290 }
1291
1292 ObjCMethodFamily getMethodFamily() const {
1293 return getOriginExpr()->getMethodFamily();
1294 }
1295
1296 Selector getSelector() const { return getOriginExpr()->getSelector(); }
1297
1298 SourceRange getSourceRange() const override;
1299
1300
1301 SVal getReceiverSVal() const;
1302
1303
1304
1305
1306
1307 const ObjCInterfaceDecl *getReceiverInterface() const {
1308 return getOriginExpr()->getReceiverInterface();
1309 }
1310
1311
1312 bool isReceiverSelfOrSuper() const;
1313
1314
1315
1316 ObjCMessageKind getMessageKind() const;
1317
1318
1319
1320 bool isSetter() const {
1321 switch (getMessageKind()) {
1322 case OCM_Message:
1323 llvm_unreachable("This is not a pseudo-object access!");
1324 case OCM_PropertyAccess:
1325 return getNumArgs() > 0;
1326 case OCM_Subscript:
1327 return getNumArgs() > 1;
1328 }
1329 llvm_unreachable("Unknown message kind");
1330 }
1331
1332
1333
1334
1335 const ObjCPropertyDecl *getAccessedProperty() const;
1336
1337 RuntimeDefinition getRuntimeDefinition() const override;
1338
1339 bool argumentsMayEscape() const override;
1340
1341 void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
1342 BindingsTy &Bindings) const override;
1343
1344 ArrayRef<ParmVarDecl *> parameters() const override;
1345
1346 Kind getKind() const override { return CE_ObjCMessage; }
1347 StringRef getKindAsString() const override { return "ObjCMethodCall"; }
1348
1349 static bool classof(const CallEvent *CA) {
1350 return CA->getKind() == CE_ObjCMessage;
1351 }
1352 };
1353
1354
1355
1356
1357
1358
1359
1360
1361 class CallEventManager {
1362 friend class CallEvent;
1363
1364 llvm::BumpPtrAllocator &Alloc;
1365 SmallVector<void *, 8> Cache;
1366
1367 using CallEventTemplateTy = SimpleFunctionCall;
1368
1369 void reclaim(const void *Memory) {
1370 Cache.push_back(const_cast<void *>(Memory));
1371 }
1372
1373
1374 void *allocate() {
1375 if (Cache.empty())
1376 return Alloc.Allocate<CallEventTemplateTy>();
1377 else
1378 return Cache.pop_back_val();
1379 }
1380
1381 template <typename T, typename Arg>
1382 T *create(Arg A, ProgramStateRef St, const LocationContext *LCtx,
1383 CFGBlock::ConstCFGElementRef ElemRef) {
1384 static_assert(sizeof(T) == sizeof(CallEventTemplateTy),
1385 "CallEvent subclasses are not all the same size");
1386 return new (allocate()) T(A, St, LCtx, ElemRef);
1387 }
1388
1389 template <typename T, typename Arg1, typename Arg2>
1390 T *create(Arg1 A1, Arg2 A2, ProgramStateRef St, const LocationContext *LCtx,
1391 CFGBlock::ConstCFGElementRef ElemRef) {
1392 static_assert(sizeof(T) == sizeof(CallEventTemplateTy),
1393 "CallEvent subclasses are not all the same size");
1394 return new (allocate()) T(A1, A2, St, LCtx, ElemRef);
1395 }
1396
1397 template <typename T, typename Arg1, typename Arg2, typename Arg3>
1398 T *create(Arg1 A1, Arg2 A2, Arg3 A3, ProgramStateRef St,
1399 const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef) {
1400 static_assert(sizeof(T) == sizeof(CallEventTemplateTy),
1401 "CallEvent subclasses are not all the same size");
1402 return new (allocate()) T(A1, A2, A3, St, LCtx, ElemRef);
1403 }
1404
1405 template <typename T, typename Arg1, typename Arg2, typename Arg3,
1406 typename Arg4>
1407 T *create(Arg1 A1, Arg2 A2, Arg3 A3, Arg4 A4, ProgramStateRef St,
1408 const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef) {
1409 static_assert(sizeof(T) == sizeof(CallEventTemplateTy),
1410 "CallEvent subclasses are not all the same size");
1411 return new (allocate()) T(A1, A2, A3, A4, St, LCtx, ElemRef);
1412 }
1413
1414 public:
1415 CallEventManager(llvm::BumpPtrAllocator &alloc) : Alloc(alloc) {}
1416
1417
1418 CallEventRef<> getCaller(const StackFrameContext *CalleeCtx,
1419 ProgramStateRef State);
1420
1421
1422
1423 CallEventRef<> getCall(const Stmt *S, ProgramStateRef State,
1424 const LocationContext *LC,
1425 CFGBlock::ConstCFGElementRef ElemRef);
1426
1427 CallEventRef<> getSimpleCall(const CallExpr *E, ProgramStateRef State,
1428 const LocationContext *LCtx,
1429 CFGBlock::ConstCFGElementRef ElemRef);
1430
1431 CallEventRef<ObjCMethodCall>
1432 getObjCMethodCall(const ObjCMessageExpr *E, ProgramStateRef State,
1433 const LocationContext *LCtx,
1434 CFGBlock::ConstCFGElementRef ElemRef) {
1435 return create<ObjCMethodCall>(E, State, LCtx, ElemRef);
1436 }
1437
1438 CallEventRef<CXXConstructorCall>
1439 getCXXConstructorCall(const CXXConstructExpr *E, const MemRegion *Target,
1440 ProgramStateRef State, const LocationContext *LCtx,
1441 CFGBlock::ConstCFGElementRef ElemRef) {
1442 return create<CXXConstructorCall>(E, Target, State, LCtx, ElemRef);
1443 }
1444
1445 CallEventRef<CXXInheritedConstructorCall>
1446 getCXXInheritedConstructorCall(const CXXInheritedCtorInitExpr *E,
1447 const MemRegion *Target, ProgramStateRef State,
1448 const LocationContext *LCtx,
1449 CFGBlock::ConstCFGElementRef ElemRef) {
1450 return create<CXXInheritedConstructorCall>(E, Target, State, LCtx, ElemRef);
1451 }
1452
1453 CallEventRef<CXXDestructorCall>
1454 getCXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger,
1455 const MemRegion *Target, bool IsBase,
1456 ProgramStateRef State, const LocationContext *LCtx,
1457 CFGBlock::ConstCFGElementRef ElemRef) {
1458 return create<CXXDestructorCall>(DD, Trigger, Target, IsBase, State, LCtx,
1459 ElemRef);
1460 }
1461
1462 CallEventRef<CXXAllocatorCall>
1463 getCXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef State,
1464 const LocationContext *LCtx,
1465 CFGBlock::ConstCFGElementRef ElemRef) {
1466 return create<CXXAllocatorCall>(E, State, LCtx, ElemRef);
1467 }
1468
1469 CallEventRef<CXXDeallocatorCall>
1470 getCXXDeallocatorCall(const CXXDeleteExpr *E, ProgramStateRef State,
1471 const LocationContext *LCtx,
1472 CFGBlock::ConstCFGElementRef ElemRef) {
1473 return create<CXXDeallocatorCall>(E, State, LCtx, ElemRef);
1474 }
1475 };
1476
1477 template <typename T>
1478 CallEventRef<T> CallEvent::cloneWithState(ProgramStateRef NewState) const {
1479 assert(isa<T>(*this) && "Cloning to unrelated type");
1480 static_assert(sizeof(T) == sizeof(CallEvent),
1481 "Subclasses may not add fields");
1482
1483 if (NewState == State)
1484 return cast<T>(this);
1485
1486 CallEventManager &Mgr = State->getStateManager().getCallEventManager();
1487 T *Copy = static_cast<T *>(Mgr.allocate());
1488 cloneTo(Copy);
1489 assert(Copy->getKind() == this->getKind() && "Bad copy");
1490
1491 Copy->State = NewState;
1492 return Copy;
1493 }
1494
1495 inline void CallEvent::Release() const {
1496 assert(RefCount > 0 && "Reference count is already zero.");
1497 --RefCount;
1498
1499 if (RefCount > 0)
1500 return;
1501
1502 CallEventManager &Mgr = State->getStateManager().getCallEventManager();
1503 Mgr.reclaim(this);
1504
1505 this->~CallEvent();
1506 }
1507
1508 }
1509
1510 }
1511
1512 namespace llvm {
1513
1514
1515 template <class T> struct simplify_type<clang::ento::CallEventRef<T>> {
1516 using SimpleType = const T *;
1517
1518 static SimpleType getSimplifiedValue(clang::ento::CallEventRef<T> Val) {
1519 return Val.get();
1520 }
1521 };
1522
1523 }
1524
1525 #endif