Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 14 | pmbaty | 1 | //===- CallEvent.h - Wrapper for all function and method calls --*- 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 | /// \file This file defines CallEvent and its subclasses, which represent path- |
||
| 10 | /// sensitive instances of different kinds of function and method calls |
||
| 11 | /// (C, C++, and Objective-C). |
||
| 12 | // |
||
| 13 | //===----------------------------------------------------------------------===// |
||
| 14 | |||
| 15 | #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLEVENT_H |
||
| 16 | #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLEVENT_H |
||
| 17 | |||
| 18 | #include "clang/AST/Decl.h" |
||
| 19 | #include "clang/AST/DeclBase.h" |
||
| 20 | #include "clang/AST/DeclCXX.h" |
||
| 21 | #include "clang/AST/DeclObjC.h" |
||
| 22 | #include "clang/AST/Expr.h" |
||
| 23 | #include "clang/AST/ExprCXX.h" |
||
| 24 | #include "clang/AST/ExprObjC.h" |
||
| 25 | #include "clang/AST/Stmt.h" |
||
| 26 | #include "clang/AST/Type.h" |
||
| 27 | #include "clang/Basic/IdentifierTable.h" |
||
| 28 | #include "clang/Basic/LLVM.h" |
||
| 29 | #include "clang/Basic/SourceLocation.h" |
||
| 30 | #include "clang/Basic/SourceManager.h" |
||
| 31 | #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" |
||
| 32 | #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" |
||
| 33 | #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" |
||
| 34 | #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" |
||
| 35 | #include "llvm/ADT/ArrayRef.h" |
||
| 36 | #include "llvm/ADT/IntrusiveRefCntPtr.h" |
||
| 37 | #include "llvm/ADT/PointerIntPair.h" |
||
| 38 | #include "llvm/ADT/PointerUnion.h" |
||
| 39 | #include "llvm/ADT/STLExtras.h" |
||
| 40 | #include "llvm/ADT/SmallVector.h" |
||
| 41 | #include "llvm/ADT/StringRef.h" |
||
| 42 | #include "llvm/ADT/iterator_range.h" |
||
| 43 | #include "llvm/Support/Allocator.h" |
||
| 44 | #include "llvm/Support/Casting.h" |
||
| 45 | #include "llvm/Support/ErrorHandling.h" |
||
| 46 | #include <cassert> |
||
| 47 | #include <limits> |
||
| 48 | #include <optional> |
||
| 49 | #include <utility> |
||
| 50 | |||
| 51 | namespace clang { |
||
| 52 | |||
| 53 | class LocationContext; |
||
| 54 | class ProgramPoint; |
||
| 55 | class ProgramPointTag; |
||
| 56 | class StackFrameContext; |
||
| 57 | |||
| 58 | namespace ento { |
||
| 59 | |||
| 60 | enum CallEventKind { |
||
| 61 | CE_Function, |
||
| 62 | CE_CXXMember, |
||
| 63 | CE_CXXMemberOperator, |
||
| 64 | CE_CXXDestructor, |
||
| 65 | CE_BEG_CXX_INSTANCE_CALLS = CE_CXXMember, |
||
| 66 | CE_END_CXX_INSTANCE_CALLS = CE_CXXDestructor, |
||
| 67 | CE_CXXConstructor, |
||
| 68 | CE_CXXInheritedConstructor, |
||
| 69 | CE_BEG_CXX_CONSTRUCTOR_CALLS = CE_CXXConstructor, |
||
| 70 | CE_END_CXX_CONSTRUCTOR_CALLS = CE_CXXInheritedConstructor, |
||
| 71 | CE_CXXAllocator, |
||
| 72 | CE_CXXDeallocator, |
||
| 73 | CE_BEG_FUNCTION_CALLS = CE_Function, |
||
| 74 | CE_END_FUNCTION_CALLS = CE_CXXDeallocator, |
||
| 75 | CE_Block, |
||
| 76 | CE_ObjCMessage |
||
| 77 | }; |
||
| 78 | |||
| 79 | class CallEvent; |
||
| 80 | |||
| 81 | template<typename T = CallEvent> |
||
| 82 | class CallEventRef : public IntrusiveRefCntPtr<const T> { |
||
| 83 | public: |
||
| 84 | CallEventRef(const T *Call) : IntrusiveRefCntPtr<const T>(Call) {} |
||
| 85 | CallEventRef(const CallEventRef &Orig) : IntrusiveRefCntPtr<const T>(Orig) {} |
||
| 86 | |||
| 87 | CallEventRef<T> cloneWithState(ProgramStateRef State) const { |
||
| 88 | return this->get()->template cloneWithState<T>(State); |
||
| 89 | } |
||
| 90 | |||
| 91 | // Allow implicit conversions to a superclass type, since CallEventRef |
||
| 92 | // behaves like a pointer-to-const. |
||
| 93 | template <typename SuperT> |
||
| 94 | operator CallEventRef<SuperT> () const { |
||
| 95 | return this->get(); |
||
| 96 | } |
||
| 97 | }; |
||
| 98 | |||
| 99 | /// \class RuntimeDefinition |
||
| 100 | /// Defines the runtime definition of the called function. |
||
| 101 | /// |
||
| 102 | /// Encapsulates the information we have about which Decl will be used |
||
| 103 | /// when the call is executed on the given path. When dealing with dynamic |
||
| 104 | /// dispatch, the information is based on DynamicTypeInfo and might not be |
||
| 105 | /// precise. |
||
| 106 | class RuntimeDefinition { |
||
| 107 | /// The Declaration of the function which could be called at runtime. |
||
| 108 | /// NULL if not available. |
||
| 109 | const Decl *D = nullptr; |
||
| 110 | |||
| 111 | /// The region representing an object (ObjC/C++) on which the method is |
||
| 112 | /// called. With dynamic dispatch, the method definition depends on the |
||
| 113 | /// runtime type of this object. NULL when the DynamicTypeInfo is |
||
| 114 | /// precise. |
||
| 115 | const MemRegion *R = nullptr; |
||
| 116 | |||
| 117 | /// A definition is foreign if it has been imported and newly created by the |
||
| 118 | /// ASTImporter. This can be true only if CTU is enabled. |
||
| 119 | const bool Foreign = false; |
||
| 120 | |||
| 121 | public: |
||
| 122 | RuntimeDefinition() = default; |
||
| 123 | RuntimeDefinition(const Decl *InD): D(InD) {} |
||
| 124 | RuntimeDefinition(const Decl *InD, bool Foreign) : D(InD), Foreign(Foreign) {} |
||
| 125 | RuntimeDefinition(const Decl *InD, const MemRegion *InR): D(InD), R(InR) {} |
||
| 126 | |||
| 127 | const Decl *getDecl() { return D; } |
||
| 128 | bool isForeign() const { return Foreign; } |
||
| 129 | |||
| 130 | /// Check if the definition we have is precise. |
||
| 131 | /// If not, it is possible that the call dispatches to another definition at |
||
| 132 | /// execution time. |
||
| 133 | bool mayHaveOtherDefinitions() { return R != nullptr; } |
||
| 134 | |||
| 135 | /// When other definitions are possible, returns the region whose runtime type |
||
| 136 | /// determines the method definition. |
||
| 137 | const MemRegion *getDispatchRegion() { return R; } |
||
| 138 | }; |
||
| 139 | |||
| 140 | /// Represents an abstract call to a function or method along a |
||
| 141 | /// particular path. |
||
| 142 | /// |
||
| 143 | /// CallEvents are created through the factory methods of CallEventManager. |
||
| 144 | /// |
||
| 145 | /// CallEvents should always be cheap to create and destroy. In order for |
||
| 146 | /// CallEventManager to be able to re-use CallEvent-sized memory blocks, |
||
| 147 | /// subclasses of CallEvent may not add any data members to the base class. |
||
| 148 | /// Use the "Data" and "Location" fields instead. |
||
| 149 | class CallEvent { |
||
| 150 | public: |
||
| 151 | using Kind = CallEventKind; |
||
| 152 | |||
| 153 | private: |
||
| 154 | ProgramStateRef State; |
||
| 155 | const LocationContext *LCtx; |
||
| 156 | llvm::PointerUnion<const Expr *, const Decl *> Origin; |
||
| 157 | mutable std::optional<bool> Foreign; // Set by CTU analysis. |
||
| 158 | |||
| 159 | protected: |
||
| 160 | // This is user data for subclasses. |
||
| 161 | const void *Data; |
||
| 162 | |||
| 163 | // This is user data for subclasses. |
||
| 164 | // This should come right before RefCount, so that the two fields can be |
||
| 165 | // packed together on LP64 platforms. |
||
| 166 | SourceLocation Location; |
||
| 167 | |||
| 168 | private: |
||
| 169 | template <typename T> friend struct llvm::IntrusiveRefCntPtrInfo; |
||
| 170 | |||
| 171 | mutable unsigned RefCount = 0; |
||
| 172 | |||
| 173 | void Retain() const { ++RefCount; } |
||
| 174 | void Release() const; |
||
| 175 | |||
| 176 | protected: |
||
| 177 | friend class CallEventManager; |
||
| 178 | |||
| 179 | CallEvent(const Expr *E, ProgramStateRef state, const LocationContext *lctx) |
||
| 180 | : State(std::move(state)), LCtx(lctx), Origin(E) {} |
||
| 181 | |||
| 182 | CallEvent(const Decl *D, ProgramStateRef state, const LocationContext *lctx) |
||
| 183 | : State(std::move(state)), LCtx(lctx), Origin(D) {} |
||
| 184 | |||
| 185 | // DO NOT MAKE PUBLIC |
||
| 186 | CallEvent(const CallEvent &Original) |
||
| 187 | : State(Original.State), LCtx(Original.LCtx), Origin(Original.Origin), |
||
| 188 | Data(Original.Data), Location(Original.Location) {} |
||
| 189 | |||
| 190 | /// Copies this CallEvent, with vtable intact, into a new block of memory. |
||
| 191 | virtual void cloneTo(void *Dest) const = 0; |
||
| 192 | |||
| 193 | /// Get the value of arbitrary expressions at this point in the path. |
||
| 194 | SVal getSVal(const Stmt *S) const { |
||
| 195 | return getState()->getSVal(S, getLocationContext()); |
||
| 196 | } |
||
| 197 | |||
| 198 | using ValueList = SmallVectorImpl<SVal>; |
||
| 199 | |||
| 200 | /// Used to specify non-argument regions that will be invalidated as a |
||
| 201 | /// result of this call. |
||
| 202 | virtual void getExtraInvalidatedValues(ValueList &Values, |
||
| 203 | RegionAndSymbolInvalidationTraits *ETraits) const {} |
||
| 204 | |||
| 205 | public: |
||
| 206 | CallEvent &operator=(const CallEvent &) = delete; |
||
| 207 | virtual ~CallEvent() = default; |
||
| 208 | |||
| 209 | /// Returns the kind of call this is. |
||
| 210 | virtual Kind getKind() const = 0; |
||
| 211 | virtual StringRef getKindAsString() const = 0; |
||
| 212 | |||
| 213 | /// Returns the declaration of the function or method that will be |
||
| 214 | /// called. May be null. |
||
| 215 | virtual const Decl *getDecl() const { |
||
| 216 | return Origin.dyn_cast<const Decl *>(); |
||
| 217 | } |
||
| 218 | |||
| 219 | bool isForeign() const { |
||
| 220 | assert(Foreign && "Foreign must be set before querying"); |
||
| 221 | return *Foreign; |
||
| 222 | } |
||
| 223 | void setForeign(bool B) const { Foreign = B; } |
||
| 224 | |||
| 225 | /// The state in which the call is being evaluated. |
||
| 226 | const ProgramStateRef &getState() const { |
||
| 227 | return State; |
||
| 228 | } |
||
| 229 | |||
| 230 | /// The context in which the call is being evaluated. |
||
| 231 | const LocationContext *getLocationContext() const { |
||
| 232 | return LCtx; |
||
| 233 | } |
||
| 234 | |||
| 235 | /// Returns the definition of the function or method that will be |
||
| 236 | /// called. |
||
| 237 | virtual RuntimeDefinition getRuntimeDefinition() const = 0; |
||
| 238 | |||
| 239 | /// Returns the expression whose value will be the result of this call. |
||
| 240 | /// May be null. |
||
| 241 | virtual const Expr *getOriginExpr() const { |
||
| 242 | return Origin.dyn_cast<const Expr *>(); |
||
| 243 | } |
||
| 244 | |||
| 245 | /// Returns the number of arguments (explicit and implicit). |
||
| 246 | /// |
||
| 247 | /// Note that this may be greater than the number of parameters in the |
||
| 248 | /// callee's declaration, and that it may include arguments not written in |
||
| 249 | /// the source. |
||
| 250 | virtual unsigned getNumArgs() const = 0; |
||
| 251 | |||
| 252 | /// Returns true if the callee is known to be from a system header. |
||
| 253 | bool isInSystemHeader() const { |
||
| 254 | const Decl *D = getDecl(); |
||
| 255 | if (!D) |
||
| 256 | return false; |
||
| 257 | |||
| 258 | SourceLocation Loc = D->getLocation(); |
||
| 259 | if (Loc.isValid()) { |
||
| 260 | const SourceManager &SM = |
||
| 261 | getState()->getStateManager().getContext().getSourceManager(); |
||
| 262 | return SM.isInSystemHeader(D->getLocation()); |
||
| 263 | } |
||
| 264 | |||
| 265 | // Special case for implicitly-declared global operator new/delete. |
||
| 266 | // These should be considered system functions. |
||
| 267 | if (const auto *FD = dyn_cast<FunctionDecl>(D)) |
||
| 268 | return FD->isOverloadedOperator() && FD->isImplicit() && FD->isGlobal(); |
||
| 269 | |||
| 270 | return false; |
||
| 271 | } |
||
| 272 | |||
| 273 | /// Returns a source range for the entire call, suitable for |
||
| 274 | /// outputting in diagnostics. |
||
| 275 | virtual SourceRange getSourceRange() const { |
||
| 276 | return getOriginExpr()->getSourceRange(); |
||
| 277 | } |
||
| 278 | |||
| 279 | /// Returns the value of a given argument at the time of the call. |
||
| 280 | virtual SVal getArgSVal(unsigned Index) const; |
||
| 281 | |||
| 282 | /// Returns the expression associated with a given argument. |
||
| 283 | /// May be null if this expression does not appear in the source. |
||
| 284 | virtual const Expr *getArgExpr(unsigned Index) const { return nullptr; } |
||
| 285 | |||
| 286 | /// Returns the source range for errors associated with this argument. |
||
| 287 | /// |
||
| 288 | /// May be invalid if the argument is not written in the source. |
||
| 289 | virtual SourceRange getArgSourceRange(unsigned Index) const; |
||
| 290 | |||
| 291 | /// Returns the result type, adjusted for references. |
||
| 292 | QualType getResultType() const; |
||
| 293 | |||
| 294 | /// Returns the return value of the call. |
||
| 295 | /// |
||
| 296 | /// This should only be called if the CallEvent was created using a state in |
||
| 297 | /// which the return value has already been bound to the origin expression. |
||
| 298 | SVal getReturnValue() const; |
||
| 299 | |||
| 300 | /// Returns true if the type of any of the non-null arguments satisfies |
||
| 301 | /// the condition. |
||
| 302 | bool hasNonNullArgumentsWithType(bool (*Condition)(QualType)) const; |
||
| 303 | |||
| 304 | /// Returns true if any of the arguments appear to represent callbacks. |
||
| 305 | bool hasNonZeroCallbackArg() const; |
||
| 306 | |||
| 307 | /// Returns true if any of the arguments is void*. |
||
| 308 | bool hasVoidPointerToNonConstArg() const; |
||
| 309 | |||
| 310 | /// Returns true if any of the arguments are known to escape to long- |
||
| 311 | /// term storage, even if this method will not modify them. |
||
| 312 | // NOTE: The exact semantics of this are still being defined! |
||
| 313 | // We don't really want a list of hardcoded exceptions in the long run, |
||
| 314 | // but we don't want duplicated lists of known APIs in the short term either. |
||
| 315 | virtual bool argumentsMayEscape() const { |
||
| 316 | return hasNonZeroCallbackArg(); |
||
| 317 | } |
||
| 318 | |||
| 319 | /// Returns true if the callee is an externally-visible function in the |
||
| 320 | /// top-level namespace, such as \c malloc. |
||
| 321 | /// |
||
| 322 | /// You can use this call to determine that a particular function really is |
||
| 323 | /// a library function and not, say, a C++ member function with the same name. |
||
| 324 | /// |
||
| 325 | /// If a name is provided, the function must additionally match the given |
||
| 326 | /// name. |
||
| 327 | /// |
||
| 328 | /// Note that this deliberately excludes C++ library functions in the \c std |
||
| 329 | /// namespace, but will include C library functions accessed through the |
||
| 330 | /// \c std namespace. This also does not check if the function is declared |
||
| 331 | /// as 'extern "C"', or if it uses C++ name mangling. |
||
| 332 | // FIXME: Add a helper for checking namespaces. |
||
| 333 | // FIXME: Move this down to AnyFunctionCall once checkers have more |
||
| 334 | // precise callbacks. |
||
| 335 | bool isGlobalCFunction(StringRef SpecificName = StringRef()) const; |
||
| 336 | |||
| 337 | /// Returns the name of the callee, if its name is a simple identifier. |
||
| 338 | /// |
||
| 339 | /// Note that this will fail for Objective-C methods, blocks, and C++ |
||
| 340 | /// overloaded operators. The former is named by a Selector rather than a |
||
| 341 | /// simple identifier, and the latter two do not have names. |
||
| 342 | // FIXME: Move this down to AnyFunctionCall once checkers have more |
||
| 343 | // precise callbacks. |
||
| 344 | const IdentifierInfo *getCalleeIdentifier() const { |
||
| 345 | const auto *ND = dyn_cast_or_null<NamedDecl>(getDecl()); |
||
| 346 | if (!ND) |
||
| 347 | return nullptr; |
||
| 348 | return ND->getIdentifier(); |
||
| 349 | } |
||
| 350 | |||
| 351 | /// Returns an appropriate ProgramPoint for this call. |
||
| 352 | ProgramPoint getProgramPoint(bool IsPreVisit = false, |
||
| 353 | const ProgramPointTag *Tag = nullptr) const; |
||
| 354 | |||
| 355 | /// Returns a new state with all argument regions invalidated. |
||
| 356 | /// |
||
| 357 | /// This accepts an alternate state in case some processing has already |
||
| 358 | /// occurred. |
||
| 359 | ProgramStateRef invalidateRegions(unsigned BlockCount, |
||
| 360 | ProgramStateRef Orig = nullptr) const; |
||
| 361 | |||
| 362 | using FrameBindingTy = std::pair<SVal, SVal>; |
||
| 363 | using BindingsTy = SmallVectorImpl<FrameBindingTy>; |
||
| 364 | |||
| 365 | /// Populates the given SmallVector with the bindings in the callee's stack |
||
| 366 | /// frame at the start of this call. |
||
| 367 | virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, |
||
| 368 | BindingsTy &Bindings) const = 0; |
||
| 369 | |||
| 370 | /// Returns a copy of this CallEvent, but using the given state. |
||
| 371 | template <typename T> |
||
| 372 | CallEventRef<T> cloneWithState(ProgramStateRef NewState) const; |
||
| 373 | |||
| 374 | /// Returns a copy of this CallEvent, but using the given state. |
||
| 375 | CallEventRef<> cloneWithState(ProgramStateRef NewState) const { |
||
| 376 | return cloneWithState<CallEvent>(NewState); |
||
| 377 | } |
||
| 378 | |||
| 379 | /// Returns true if this is a statement is a function or method call |
||
| 380 | /// of some kind. |
||
| 381 | static bool isCallStmt(const Stmt *S); |
||
| 382 | |||
| 383 | /// Returns the result type of a function or method declaration. |
||
| 384 | /// |
||
| 385 | /// This will return a null QualType if the result type cannot be determined. |
||
| 386 | static QualType getDeclaredResultType(const Decl *D); |
||
| 387 | |||
| 388 | /// Returns true if the given decl is known to be variadic. |
||
| 389 | /// |
||
| 390 | /// \p D must not be null. |
||
| 391 | static bool isVariadic(const Decl *D); |
||
| 392 | |||
| 393 | /// Returns AnalysisDeclContext for the callee stack frame. |
||
| 394 | /// Currently may fail; returns null on failure. |
||
| 395 | AnalysisDeclContext *getCalleeAnalysisDeclContext() const; |
||
| 396 | |||
| 397 | /// Returns the callee stack frame. That stack frame will only be entered |
||
| 398 | /// during analysis if the call is inlined, but it may still be useful |
||
| 399 | /// in intermediate calculations even if the call isn't inlined. |
||
| 400 | /// May fail; returns null on failure. |
||
| 401 | const StackFrameContext *getCalleeStackFrame(unsigned BlockCount) const; |
||
| 402 | |||
| 403 | /// Returns memory location for a parameter variable within the callee stack |
||
| 404 | /// frame. The behavior is undefined if the block count is different from the |
||
| 405 | /// one that is there when call happens. May fail; returns null on failure. |
||
| 406 | const ParamVarRegion *getParameterLocation(unsigned Index, |
||
| 407 | unsigned BlockCount) const; |
||
| 408 | |||
| 409 | /// Returns true if on the current path, the argument was constructed by |
||
| 410 | /// calling a C++ constructor over it. This is an internal detail of the |
||
| 411 | /// analysis which doesn't necessarily represent the program semantics: |
||
| 412 | /// if we are supposed to construct an argument directly, we may still |
||
| 413 | /// not do that because we don't know how (i.e., construction context is |
||
| 414 | /// unavailable in the CFG or not supported by the analyzer). |
||
| 415 | bool isArgumentConstructedDirectly(unsigned Index) const { |
||
| 416 | // This assumes that the object was not yet removed from the state. |
||
| 417 | return ExprEngine::getObjectUnderConstruction( |
||
| 418 | getState(), {getOriginExpr(), Index}, getLocationContext()) |
||
| 419 | .has_value(); |
||
| 420 | } |
||
| 421 | |||
| 422 | /// Some calls have parameter numbering mismatched from argument numbering. |
||
| 423 | /// This function converts an argument index to the corresponding |
||
| 424 | /// parameter index. Returns std::nullopt is the argument doesn't correspond |
||
| 425 | /// to any parameter variable. |
||
| 426 | virtual std::optional<unsigned> |
||
| 427 | getAdjustedParameterIndex(unsigned ASTArgumentIndex) const { |
||
| 428 | return ASTArgumentIndex; |
||
| 429 | } |
||
| 430 | |||
| 431 | /// Some call event sub-classes conveniently adjust mismatching AST indices |
||
| 432 | /// to match parameter indices. This function converts an argument index |
||
| 433 | /// as understood by CallEvent to the argument index as understood by the AST. |
||
| 434 | virtual unsigned getASTArgumentIndex(unsigned CallArgumentIndex) const { |
||
| 435 | return CallArgumentIndex; |
||
| 436 | } |
||
| 437 | |||
| 438 | /// Returns the construction context of the call, if it is a C++ constructor |
||
| 439 | /// call or a call of a function returning a C++ class instance. Otherwise |
||
| 440 | /// return nullptr. |
||
| 441 | const ConstructionContext *getConstructionContext() const; |
||
| 442 | |||
| 443 | /// If the call returns a C++ record type then the region of its return value |
||
| 444 | /// can be retrieved from its construction context. |
||
| 445 | std::optional<SVal> getReturnValueUnderConstruction() const; |
||
| 446 | |||
| 447 | // Iterator access to formal parameters and their types. |
||
| 448 | private: |
||
| 449 | struct GetTypeFn { |
||
| 450 | QualType operator()(ParmVarDecl *PD) const { return PD->getType(); } |
||
| 451 | }; |
||
| 452 | |||
| 453 | public: |
||
| 454 | /// Return call's formal parameters. |
||
| 455 | /// |
||
| 456 | /// Remember that the number of formal parameters may not match the number |
||
| 457 | /// of arguments for all calls. However, the first parameter will always |
||
| 458 | /// correspond with the argument value returned by \c getArgSVal(0). |
||
| 459 | virtual ArrayRef<ParmVarDecl *> parameters() const = 0; |
||
| 460 | |||
| 461 | using param_type_iterator = |
||
| 462 | llvm::mapped_iterator<ArrayRef<ParmVarDecl *>::iterator, GetTypeFn>; |
||
| 463 | |||
| 464 | /// Returns an iterator over the types of the call's formal parameters. |
||
| 465 | /// |
||
| 466 | /// This uses the callee decl found by default name lookup rather than the |
||
| 467 | /// definition because it represents a public interface, and probably has |
||
| 468 | /// more annotations. |
||
| 469 | param_type_iterator param_type_begin() const { |
||
| 470 | return llvm::map_iterator(parameters().begin(), GetTypeFn()); |
||
| 471 | } |
||
| 472 | /// \sa param_type_begin() |
||
| 473 | param_type_iterator param_type_end() const { |
||
| 474 | return llvm::map_iterator(parameters().end(), GetTypeFn()); |
||
| 475 | } |
||
| 476 | |||
| 477 | // For debugging purposes only |
||
| 478 | void dump(raw_ostream &Out) const; |
||
| 479 | void dump() const; |
||
| 480 | }; |
||
| 481 | |||
| 482 | /// Represents a call to any sort of function that might have a |
||
| 483 | /// FunctionDecl. |
||
| 484 | class AnyFunctionCall : public CallEvent { |
||
| 485 | protected: |
||
| 486 | AnyFunctionCall(const Expr *E, ProgramStateRef St, |
||
| 487 | const LocationContext *LCtx) |
||
| 488 | : CallEvent(E, St, LCtx) {} |
||
| 489 | AnyFunctionCall(const Decl *D, ProgramStateRef St, |
||
| 490 | const LocationContext *LCtx) |
||
| 491 | : CallEvent(D, St, LCtx) {} |
||
| 492 | AnyFunctionCall(const AnyFunctionCall &Other) = default; |
||
| 493 | |||
| 494 | public: |
||
| 495 | // This function is overridden by subclasses, but they must return |
||
| 496 | // a FunctionDecl. |
||
| 497 | const FunctionDecl *getDecl() const override { |
||
| 498 | return cast<FunctionDecl>(CallEvent::getDecl()); |
||
| 499 | } |
||
| 500 | |||
| 501 | RuntimeDefinition getRuntimeDefinition() const override; |
||
| 502 | |||
| 503 | bool argumentsMayEscape() const override; |
||
| 504 | |||
| 505 | void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, |
||
| 506 | BindingsTy &Bindings) const override; |
||
| 507 | |||
| 508 | ArrayRef<ParmVarDecl *> parameters() const override; |
||
| 509 | |||
| 510 | static bool classof(const CallEvent *CA) { |
||
| 511 | return CA->getKind() >= CE_BEG_FUNCTION_CALLS && |
||
| 512 | CA->getKind() <= CE_END_FUNCTION_CALLS; |
||
| 513 | } |
||
| 514 | }; |
||
| 515 | |||
| 516 | /// Represents a C function or static C++ member function call. |
||
| 517 | /// |
||
| 518 | /// Example: \c fun() |
||
| 519 | class SimpleFunctionCall : public AnyFunctionCall { |
||
| 520 | friend class CallEventManager; |
||
| 521 | |||
| 522 | protected: |
||
| 523 | SimpleFunctionCall(const CallExpr *CE, ProgramStateRef St, |
||
| 524 | const LocationContext *LCtx) |
||
| 525 | : AnyFunctionCall(CE, St, LCtx) {} |
||
| 526 | SimpleFunctionCall(const SimpleFunctionCall &Other) = default; |
||
| 527 | |||
| 528 | void cloneTo(void *Dest) const override { |
||
| 529 | new (Dest) SimpleFunctionCall(*this); |
||
| 530 | } |
||
| 531 | |||
| 532 | public: |
||
| 533 | const CallExpr *getOriginExpr() const override { |
||
| 534 | return cast<CallExpr>(AnyFunctionCall::getOriginExpr()); |
||
| 535 | } |
||
| 536 | |||
| 537 | const FunctionDecl *getDecl() const override; |
||
| 538 | |||
| 539 | unsigned getNumArgs() const override { return getOriginExpr()->getNumArgs(); } |
||
| 540 | |||
| 541 | const Expr *getArgExpr(unsigned Index) const override { |
||
| 542 | return getOriginExpr()->getArg(Index); |
||
| 543 | } |
||
| 544 | |||
| 545 | Kind getKind() const override { return CE_Function; } |
||
| 546 | StringRef getKindAsString() const override { return "SimpleFunctionCall"; } |
||
| 547 | |||
| 548 | static bool classof(const CallEvent *CA) { |
||
| 549 | return CA->getKind() == CE_Function; |
||
| 550 | } |
||
| 551 | }; |
||
| 552 | |||
| 553 | /// Represents a call to a block. |
||
| 554 | /// |
||
| 555 | /// Example: <tt>^{ statement-body }()</tt> |
||
| 556 | class BlockCall : public CallEvent { |
||
| 557 | friend class CallEventManager; |
||
| 558 | |||
| 559 | protected: |
||
| 560 | BlockCall(const CallExpr *CE, ProgramStateRef St, |
||
| 561 | const LocationContext *LCtx) |
||
| 562 | : CallEvent(CE, St, LCtx) {} |
||
| 563 | BlockCall(const BlockCall &Other) = default; |
||
| 564 | |||
| 565 | void cloneTo(void *Dest) const override { new (Dest) BlockCall(*this); } |
||
| 566 | |||
| 567 | void getExtraInvalidatedValues(ValueList &Values, |
||
| 568 | RegionAndSymbolInvalidationTraits *ETraits) const override; |
||
| 569 | |||
| 570 | public: |
||
| 571 | const CallExpr *getOriginExpr() const override { |
||
| 572 | return cast<CallExpr>(CallEvent::getOriginExpr()); |
||
| 573 | } |
||
| 574 | |||
| 575 | unsigned getNumArgs() const override { return getOriginExpr()->getNumArgs(); } |
||
| 576 | |||
| 577 | const Expr *getArgExpr(unsigned Index) const override { |
||
| 578 | return getOriginExpr()->getArg(Index); |
||
| 579 | } |
||
| 580 | |||
| 581 | /// Returns the region associated with this instance of the block. |
||
| 582 | /// |
||
| 583 | /// This may be NULL if the block's origin is unknown. |
||
| 584 | const BlockDataRegion *getBlockRegion() const; |
||
| 585 | |||
| 586 | const BlockDecl *getDecl() const override { |
||
| 587 | const BlockDataRegion *BR = getBlockRegion(); |
||
| 588 | if (!BR) |
||
| 589 | return nullptr; |
||
| 590 | return BR->getDecl(); |
||
| 591 | } |
||
| 592 | |||
| 593 | bool isConversionFromLambda() const { |
||
| 594 | const BlockDecl *BD = getDecl(); |
||
| 595 | if (!BD) |
||
| 596 | return false; |
||
| 597 | |||
| 598 | return BD->isConversionFromLambda(); |
||
| 599 | } |
||
| 600 | |||
| 601 | /// For a block converted from a C++ lambda, returns the block |
||
| 602 | /// VarRegion for the variable holding the captured C++ lambda record. |
||
| 603 | const VarRegion *getRegionStoringCapturedLambda() const { |
||
| 604 | assert(isConversionFromLambda()); |
||
| 605 | const BlockDataRegion *BR = getBlockRegion(); |
||
| 606 | assert(BR && "Block converted from lambda must have a block region"); |
||
| 607 | |||
| 608 | auto I = BR->referenced_vars_begin(); |
||
| 609 | assert(I != BR->referenced_vars_end()); |
||
| 610 | |||
| 611 | return I.getCapturedRegion(); |
||
| 612 | } |
||
| 613 | |||
| 614 | RuntimeDefinition getRuntimeDefinition() const override { |
||
| 615 | if (!isConversionFromLambda()) |
||
| 616 | return RuntimeDefinition(getDecl()); |
||
| 617 | |||
| 618 | // Clang converts lambdas to blocks with an implicit user-defined |
||
| 619 | // conversion operator method on the lambda record that looks (roughly) |
||
| 620 | // like: |
||
| 621 | // |
||
| 622 | // typedef R(^block_type)(P1, P2, ...); |
||
| 623 | // operator block_type() const { |
||
| 624 | // auto Lambda = *this; |
||
| 625 | // return ^(P1 p1, P2 p2, ...){ |
||
| 626 | // /* return Lambda(p1, p2, ...); */ |
||
| 627 | // }; |
||
| 628 | // } |
||
| 629 | // |
||
| 630 | // Here R is the return type of the lambda and P1, P2, ... are |
||
| 631 | // its parameter types. 'Lambda' is a fake VarDecl captured by the block |
||
| 632 | // that is initialized to a copy of the lambda. |
||
| 633 | // |
||
| 634 | // Sema leaves the body of a lambda-converted block empty (it is |
||
| 635 | // produced by CodeGen), so we can't analyze it directly. Instead, we skip |
||
| 636 | // the block body and analyze the operator() method on the captured lambda. |
||
| 637 | const VarDecl *LambdaVD = getRegionStoringCapturedLambda()->getDecl(); |
||
| 638 | const CXXRecordDecl *LambdaDecl = LambdaVD->getType()->getAsCXXRecordDecl(); |
||
| 639 | CXXMethodDecl* LambdaCallOperator = LambdaDecl->getLambdaCallOperator(); |
||
| 640 | |||
| 641 | return RuntimeDefinition(LambdaCallOperator); |
||
| 642 | } |
||
| 643 | |||
| 644 | bool argumentsMayEscape() const override { |
||
| 645 | return true; |
||
| 646 | } |
||
| 647 | |||
| 648 | void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, |
||
| 649 | BindingsTy &Bindings) const override; |
||
| 650 | |||
| 651 | ArrayRef<ParmVarDecl *> parameters() const override; |
||
| 652 | |||
| 653 | Kind getKind() const override { return CE_Block; } |
||
| 654 | StringRef getKindAsString() const override { return "BlockCall"; } |
||
| 655 | |||
| 656 | static bool classof(const CallEvent *CA) { return CA->getKind() == CE_Block; } |
||
| 657 | }; |
||
| 658 | |||
| 659 | /// Represents a non-static C++ member function call, no matter how |
||
| 660 | /// it is written. |
||
| 661 | class CXXInstanceCall : public AnyFunctionCall { |
||
| 662 | protected: |
||
| 663 | CXXInstanceCall(const CallExpr *CE, ProgramStateRef St, |
||
| 664 | const LocationContext *LCtx) |
||
| 665 | : AnyFunctionCall(CE, St, LCtx) {} |
||
| 666 | CXXInstanceCall(const FunctionDecl *D, ProgramStateRef St, |
||
| 667 | const LocationContext *LCtx) |
||
| 668 | : AnyFunctionCall(D, St, LCtx) {} |
||
| 669 | CXXInstanceCall(const CXXInstanceCall &Other) = default; |
||
| 670 | |||
| 671 | void getExtraInvalidatedValues(ValueList &Values, |
||
| 672 | RegionAndSymbolInvalidationTraits *ETraits) const override; |
||
| 673 | |||
| 674 | public: |
||
| 675 | /// Returns the expression representing the implicit 'this' object. |
||
| 676 | virtual const Expr *getCXXThisExpr() const { return nullptr; } |
||
| 677 | |||
| 678 | /// Returns the value of the implicit 'this' object. |
||
| 679 | virtual SVal getCXXThisVal() const; |
||
| 680 | |||
| 681 | const FunctionDecl *getDecl() const override; |
||
| 682 | |||
| 683 | RuntimeDefinition getRuntimeDefinition() const override; |
||
| 684 | |||
| 685 | void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, |
||
| 686 | BindingsTy &Bindings) const override; |
||
| 687 | |||
| 688 | static bool classof(const CallEvent *CA) { |
||
| 689 | return CA->getKind() >= CE_BEG_CXX_INSTANCE_CALLS && |
||
| 690 | CA->getKind() <= CE_END_CXX_INSTANCE_CALLS; |
||
| 691 | } |
||
| 692 | }; |
||
| 693 | |||
| 694 | /// Represents a non-static C++ member function call. |
||
| 695 | /// |
||
| 696 | /// Example: \c obj.fun() |
||
| 697 | class CXXMemberCall : public CXXInstanceCall { |
||
| 698 | friend class CallEventManager; |
||
| 699 | |||
| 700 | protected: |
||
| 701 | CXXMemberCall(const CXXMemberCallExpr *CE, ProgramStateRef St, |
||
| 702 | const LocationContext *LCtx) |
||
| 703 | : CXXInstanceCall(CE, St, LCtx) {} |
||
| 704 | CXXMemberCall(const CXXMemberCall &Other) = default; |
||
| 705 | |||
| 706 | void cloneTo(void *Dest) const override { new (Dest) CXXMemberCall(*this); } |
||
| 707 | |||
| 708 | public: |
||
| 709 | const CXXMemberCallExpr *getOriginExpr() const override { |
||
| 710 | return cast<CXXMemberCallExpr>(CXXInstanceCall::getOriginExpr()); |
||
| 711 | } |
||
| 712 | |||
| 713 | unsigned getNumArgs() const override { |
||
| 714 | if (const CallExpr *CE = getOriginExpr()) |
||
| 715 | return CE->getNumArgs(); |
||
| 716 | return 0; |
||
| 717 | } |
||
| 718 | |||
| 719 | const Expr *getArgExpr(unsigned Index) const override { |
||
| 720 | return getOriginExpr()->getArg(Index); |
||
| 721 | } |
||
| 722 | |||
| 723 | const Expr *getCXXThisExpr() const override; |
||
| 724 | |||
| 725 | RuntimeDefinition getRuntimeDefinition() const override; |
||
| 726 | |||
| 727 | Kind getKind() const override { return CE_CXXMember; } |
||
| 728 | StringRef getKindAsString() const override { return "CXXMemberCall"; } |
||
| 729 | |||
| 730 | static bool classof(const CallEvent *CA) { |
||
| 731 | return CA->getKind() == CE_CXXMember; |
||
| 732 | } |
||
| 733 | }; |
||
| 734 | |||
| 735 | /// Represents a C++ overloaded operator call where the operator is |
||
| 736 | /// implemented as a non-static member function. |
||
| 737 | /// |
||
| 738 | /// Example: <tt>iter + 1</tt> |
||
| 739 | class CXXMemberOperatorCall : public CXXInstanceCall { |
||
| 740 | friend class CallEventManager; |
||
| 741 | |||
| 742 | protected: |
||
| 743 | CXXMemberOperatorCall(const CXXOperatorCallExpr *CE, ProgramStateRef St, |
||
| 744 | const LocationContext *LCtx) |
||
| 745 | : CXXInstanceCall(CE, St, LCtx) {} |
||
| 746 | CXXMemberOperatorCall(const CXXMemberOperatorCall &Other) = default; |
||
| 747 | |||
| 748 | void cloneTo(void *Dest) const override { |
||
| 749 | new (Dest) CXXMemberOperatorCall(*this); |
||
| 750 | } |
||
| 751 | |||
| 752 | public: |
||
| 753 | const CXXOperatorCallExpr *getOriginExpr() const override { |
||
| 754 | return cast<CXXOperatorCallExpr>(CXXInstanceCall::getOriginExpr()); |
||
| 755 | } |
||
| 756 | |||
| 757 | unsigned getNumArgs() const override { |
||
| 758 | return getOriginExpr()->getNumArgs() - 1; |
||
| 759 | } |
||
| 760 | |||
| 761 | const Expr *getArgExpr(unsigned Index) const override { |
||
| 762 | return getOriginExpr()->getArg(Index + 1); |
||
| 763 | } |
||
| 764 | |||
| 765 | const Expr *getCXXThisExpr() const override; |
||
| 766 | |||
| 767 | Kind getKind() const override { return CE_CXXMemberOperator; } |
||
| 768 | StringRef getKindAsString() const override { return "CXXMemberOperatorCall"; } |
||
| 769 | |||
| 770 | static bool classof(const CallEvent *CA) { |
||
| 771 | return CA->getKind() == CE_CXXMemberOperator; |
||
| 772 | } |
||
| 773 | |||
| 774 | std::optional<unsigned> |
||
| 775 | getAdjustedParameterIndex(unsigned ASTArgumentIndex) const override { |
||
| 776 | // For member operator calls argument 0 on the expression corresponds |
||
| 777 | // to implicit this-parameter on the declaration. |
||
| 778 | return (ASTArgumentIndex > 0) |
||
| 779 | ? std::optional<unsigned>(ASTArgumentIndex - 1) |
||
| 780 | : std::nullopt; |
||
| 781 | } |
||
| 782 | |||
| 783 | unsigned getASTArgumentIndex(unsigned CallArgumentIndex) const override { |
||
| 784 | // For member operator calls argument 0 on the expression corresponds |
||
| 785 | // to implicit this-parameter on the declaration. |
||
| 786 | return CallArgumentIndex + 1; |
||
| 787 | } |
||
| 788 | |||
| 789 | OverloadedOperatorKind getOverloadedOperator() const { |
||
| 790 | return getOriginExpr()->getOperator(); |
||
| 791 | } |
||
| 792 | }; |
||
| 793 | |||
| 794 | /// Represents an implicit call to a C++ destructor. |
||
| 795 | /// |
||
| 796 | /// This can occur at the end of a scope (for automatic objects), at the end |
||
| 797 | /// of a full-expression (for temporaries), or as part of a delete. |
||
| 798 | class CXXDestructorCall : public CXXInstanceCall { |
||
| 799 | friend class CallEventManager; |
||
| 800 | |||
| 801 | protected: |
||
| 802 | using DtorDataTy = llvm::PointerIntPair<const MemRegion *, 1, bool>; |
||
| 803 | |||
| 804 | /// Creates an implicit destructor. |
||
| 805 | /// |
||
| 806 | /// \param DD The destructor that will be called. |
||
| 807 | /// \param Trigger The statement whose completion causes this destructor call. |
||
| 808 | /// \param Target The object region to be destructed. |
||
| 809 | /// \param St The path-sensitive state at this point in the program. |
||
| 810 | /// \param LCtx The location context at this point in the program. |
||
| 811 | CXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger, |
||
| 812 | const MemRegion *Target, bool IsBaseDestructor, |
||
| 813 | ProgramStateRef St, const LocationContext *LCtx) |
||
| 814 | : CXXInstanceCall(DD, St, LCtx) { |
||
| 815 | Data = DtorDataTy(Target, IsBaseDestructor).getOpaqueValue(); |
||
| 816 | Location = Trigger->getEndLoc(); |
||
| 817 | } |
||
| 818 | |||
| 819 | CXXDestructorCall(const CXXDestructorCall &Other) = default; |
||
| 820 | |||
| 821 | void cloneTo(void *Dest) const override {new (Dest) CXXDestructorCall(*this);} |
||
| 822 | |||
| 823 | public: |
||
| 824 | SourceRange getSourceRange() const override { return Location; } |
||
| 825 | unsigned getNumArgs() const override { return 0; } |
||
| 826 | |||
| 827 | RuntimeDefinition getRuntimeDefinition() const override; |
||
| 828 | |||
| 829 | /// Returns the value of the implicit 'this' object. |
||
| 830 | SVal getCXXThisVal() const override; |
||
| 831 | |||
| 832 | /// Returns true if this is a call to a base class destructor. |
||
| 833 | bool isBaseDestructor() const { |
||
| 834 | return DtorDataTy::getFromOpaqueValue(Data).getInt(); |
||
| 835 | } |
||
| 836 | |||
| 837 | Kind getKind() const override { return CE_CXXDestructor; } |
||
| 838 | StringRef getKindAsString() const override { return "CXXDestructorCall"; } |
||
| 839 | |||
| 840 | static bool classof(const CallEvent *CA) { |
||
| 841 | return CA->getKind() == CE_CXXDestructor; |
||
| 842 | } |
||
| 843 | }; |
||
| 844 | |||
| 845 | /// Represents any constructor invocation. This includes regular constructors |
||
| 846 | /// and inherited constructors. |
||
| 847 | class AnyCXXConstructorCall : public AnyFunctionCall { |
||
| 848 | protected: |
||
| 849 | AnyCXXConstructorCall(const Expr *E, const MemRegion *Target, |
||
| 850 | ProgramStateRef St, const LocationContext *LCtx) |
||
| 851 | : AnyFunctionCall(E, St, LCtx) { |
||
| 852 | assert(E && (isa<CXXConstructExpr>(E) || isa<CXXInheritedCtorInitExpr>(E))); |
||
| 853 | // Target may be null when the region is unknown. |
||
| 854 | Data = Target; |
||
| 855 | } |
||
| 856 | |||
| 857 | void getExtraInvalidatedValues(ValueList &Values, |
||
| 858 | RegionAndSymbolInvalidationTraits *ETraits) const override; |
||
| 859 | |||
| 860 | void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, |
||
| 861 | BindingsTy &Bindings) const override; |
||
| 862 | |||
| 863 | public: |
||
| 864 | /// Returns the value of the implicit 'this' object. |
||
| 865 | SVal getCXXThisVal() const; |
||
| 866 | |||
| 867 | static bool classof(const CallEvent *Call) { |
||
| 868 | return Call->getKind() >= CE_BEG_CXX_CONSTRUCTOR_CALLS && |
||
| 869 | Call->getKind() <= CE_END_CXX_CONSTRUCTOR_CALLS; |
||
| 870 | } |
||
| 871 | }; |
||
| 872 | |||
| 873 | /// Represents a call to a C++ constructor. |
||
| 874 | /// |
||
| 875 | /// Example: \c T(1) |
||
| 876 | class CXXConstructorCall : public AnyCXXConstructorCall { |
||
| 877 | friend class CallEventManager; |
||
| 878 | |||
| 879 | protected: |
||
| 880 | /// Creates a constructor call. |
||
| 881 | /// |
||
| 882 | /// \param CE The constructor expression as written in the source. |
||
| 883 | /// \param Target The region where the object should be constructed. If NULL, |
||
| 884 | /// a new symbolic region will be used. |
||
| 885 | /// \param St The path-sensitive state at this point in the program. |
||
| 886 | /// \param LCtx The location context at this point in the program. |
||
| 887 | CXXConstructorCall(const CXXConstructExpr *CE, const MemRegion *Target, |
||
| 888 | ProgramStateRef St, const LocationContext *LCtx) |
||
| 889 | : AnyCXXConstructorCall(CE, Target, St, LCtx) {} |
||
| 890 | |||
| 891 | CXXConstructorCall(const CXXConstructorCall &Other) = default; |
||
| 892 | |||
| 893 | void cloneTo(void *Dest) const override { new (Dest) CXXConstructorCall(*this); } |
||
| 894 | |||
| 895 | public: |
||
| 896 | const CXXConstructExpr *getOriginExpr() const override { |
||
| 897 | return cast<CXXConstructExpr>(AnyFunctionCall::getOriginExpr()); |
||
| 898 | } |
||
| 899 | |||
| 900 | const CXXConstructorDecl *getDecl() const override { |
||
| 901 | return getOriginExpr()->getConstructor(); |
||
| 902 | } |
||
| 903 | |||
| 904 | unsigned getNumArgs() const override { return getOriginExpr()->getNumArgs(); } |
||
| 905 | |||
| 906 | const Expr *getArgExpr(unsigned Index) const override { |
||
| 907 | return getOriginExpr()->getArg(Index); |
||
| 908 | } |
||
| 909 | |||
| 910 | Kind getKind() const override { return CE_CXXConstructor; } |
||
| 911 | StringRef getKindAsString() const override { return "CXXConstructorCall"; } |
||
| 912 | |||
| 913 | static bool classof(const CallEvent *CA) { |
||
| 914 | return CA->getKind() == CE_CXXConstructor; |
||
| 915 | } |
||
| 916 | }; |
||
| 917 | |||
| 918 | /// Represents a call to a C++ inherited constructor. |
||
| 919 | /// |
||
| 920 | /// Example: \c class T : public S { using S::S; }; T(1); |
||
| 921 | /// |
||
| 922 | // Note, it is difficult to model the parameters. This is one of the reasons |
||
| 923 | // why we skip analysis of inheriting constructors as top-level functions. |
||
| 924 | // CXXInheritedCtorInitExpr doesn't take arguments and doesn't model parameter |
||
| 925 | // initialization because there is none: the arguments in the outer |
||
| 926 | // CXXConstructExpr directly initialize the parameters of the base class |
||
| 927 | // constructor, and no copies are made. (Making a copy of the parameter is |
||
| 928 | // incorrect, at least if it's done in an observable way.) The derived class |
||
| 929 | // constructor doesn't even exist in the formal model. |
||
| 930 | /// E.g., in: |
||
| 931 | /// |
||
| 932 | /// struct X { X *p = this; ~X() {} }; |
||
| 933 | /// struct A { A(X x) : b(x.p == &x) {} bool b; }; |
||
| 934 | /// struct B : A { using A::A; }; |
||
| 935 | /// B b = X{}; |
||
| 936 | /// |
||
| 937 | /// ... b.b is initialized to true. |
||
| 938 | class CXXInheritedConstructorCall : public AnyCXXConstructorCall { |
||
| 939 | friend class CallEventManager; |
||
| 940 | |||
| 941 | protected: |
||
| 942 | CXXInheritedConstructorCall(const CXXInheritedCtorInitExpr *CE, |
||
| 943 | const MemRegion *Target, ProgramStateRef St, |
||
| 944 | const LocationContext *LCtx) |
||
| 945 | : AnyCXXConstructorCall(CE, Target, St, LCtx) {} |
||
| 946 | |||
| 947 | CXXInheritedConstructorCall(const CXXInheritedConstructorCall &Other) = |
||
| 948 | default; |
||
| 949 | |||
| 950 | void cloneTo(void *Dest) const override { |
||
| 951 | new (Dest) CXXInheritedConstructorCall(*this); |
||
| 952 | } |
||
| 953 | |||
| 954 | public: |
||
| 955 | const CXXInheritedCtorInitExpr *getOriginExpr() const override { |
||
| 956 | return cast<CXXInheritedCtorInitExpr>(AnyFunctionCall::getOriginExpr()); |
||
| 957 | } |
||
| 958 | |||
| 959 | const CXXConstructorDecl *getDecl() const override { |
||
| 960 | return getOriginExpr()->getConstructor(); |
||
| 961 | } |
||
| 962 | |||
| 963 | /// Obtain the stack frame of the inheriting constructor. Argument expressions |
||
| 964 | /// can be found on the call site of that stack frame. |
||
| 965 | const StackFrameContext *getInheritingStackFrame() const; |
||
| 966 | |||
| 967 | /// Obtain the CXXConstructExpr for the sub-class that inherited the current |
||
| 968 | /// constructor (possibly indirectly). It's the statement that contains |
||
| 969 | /// argument expressions. |
||
| 970 | const CXXConstructExpr *getInheritingConstructor() const { |
||
| 971 | return cast<CXXConstructExpr>(getInheritingStackFrame()->getCallSite()); |
||
| 972 | } |
||
| 973 | |||
| 974 | unsigned getNumArgs() const override { |
||
| 975 | return getInheritingConstructor()->getNumArgs(); |
||
| 976 | } |
||
| 977 | |||
| 978 | const Expr *getArgExpr(unsigned Index) const override { |
||
| 979 | return getInheritingConstructor()->getArg(Index); |
||
| 980 | } |
||
| 981 | |||
| 982 | SVal getArgSVal(unsigned Index) const override { |
||
| 983 | return getState()->getSVal( |
||
| 984 | getArgExpr(Index), |
||
| 985 | getInheritingStackFrame()->getParent()->getStackFrame()); |
||
| 986 | } |
||
| 987 | |||
| 988 | Kind getKind() const override { return CE_CXXInheritedConstructor; } |
||
| 989 | StringRef getKindAsString() const override { |
||
| 990 | return "CXXInheritedConstructorCall"; |
||
| 991 | } |
||
| 992 | |||
| 993 | static bool classof(const CallEvent *CA) { |
||
| 994 | return CA->getKind() == CE_CXXInheritedConstructor; |
||
| 995 | } |
||
| 996 | }; |
||
| 997 | |||
| 998 | /// Represents the memory allocation call in a C++ new-expression. |
||
| 999 | /// |
||
| 1000 | /// This is a call to "operator new". |
||
| 1001 | class CXXAllocatorCall : public AnyFunctionCall { |
||
| 1002 | friend class CallEventManager; |
||
| 1003 | |||
| 1004 | protected: |
||
| 1005 | CXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef St, |
||
| 1006 | const LocationContext *LCtx) |
||
| 1007 | : AnyFunctionCall(E, St, LCtx) {} |
||
| 1008 | CXXAllocatorCall(const CXXAllocatorCall &Other) = default; |
||
| 1009 | |||
| 1010 | void cloneTo(void *Dest) const override { new (Dest) CXXAllocatorCall(*this); } |
||
| 1011 | |||
| 1012 | public: |
||
| 1013 | const CXXNewExpr *getOriginExpr() const override { |
||
| 1014 | return cast<CXXNewExpr>(AnyFunctionCall::getOriginExpr()); |
||
| 1015 | } |
||
| 1016 | |||
| 1017 | const FunctionDecl *getDecl() const override { |
||
| 1018 | return getOriginExpr()->getOperatorNew(); |
||
| 1019 | } |
||
| 1020 | |||
| 1021 | SVal getObjectUnderConstruction() const { |
||
| 1022 | return *ExprEngine::getObjectUnderConstruction(getState(), getOriginExpr(), |
||
| 1023 | getLocationContext()); |
||
| 1024 | } |
||
| 1025 | |||
| 1026 | /// Number of non-placement arguments to the call. It is equal to 2 for |
||
| 1027 | /// C++17 aligned operator new() calls that have alignment implicitly |
||
| 1028 | /// passed as the second argument, and to 1 for other operator new() calls. |
||
| 1029 | unsigned getNumImplicitArgs() const { |
||
| 1030 | return getOriginExpr()->passAlignment() ? 2 : 1; |
||
| 1031 | } |
||
| 1032 | |||
| 1033 | unsigned getNumArgs() const override { |
||
| 1034 | return getOriginExpr()->getNumPlacementArgs() + getNumImplicitArgs(); |
||
| 1035 | } |
||
| 1036 | |||
| 1037 | bool isArray() const { return getOriginExpr()->isArray(); } |
||
| 1038 | |||
| 1039 | std::optional<const clang::Expr *> getArraySizeExpr() const { |
||
| 1040 | return getOriginExpr()->getArraySize(); |
||
| 1041 | } |
||
| 1042 | |||
| 1043 | SVal getArraySizeVal() const { |
||
| 1044 | assert(isArray() && "The allocator call doesn't allocate and array!"); |
||
| 1045 | |||
| 1046 | return getState()->getSVal(*getArraySizeExpr(), getLocationContext()); |
||
| 1047 | } |
||
| 1048 | |||
| 1049 | const Expr *getArgExpr(unsigned Index) const override { |
||
| 1050 | // The first argument of an allocator call is the size of the allocation. |
||
| 1051 | if (Index < getNumImplicitArgs()) |
||
| 1052 | return nullptr; |
||
| 1053 | return getOriginExpr()->getPlacementArg(Index - getNumImplicitArgs()); |
||
| 1054 | } |
||
| 1055 | |||
| 1056 | /// Number of placement arguments to the operator new() call. For example, |
||
| 1057 | /// standard std::nothrow operator new and standard placement new both have |
||
| 1058 | /// 1 implicit argument (size) and 1 placement argument, while regular |
||
| 1059 | /// operator new() has 1 implicit argument and 0 placement arguments. |
||
| 1060 | const Expr *getPlacementArgExpr(unsigned Index) const { |
||
| 1061 | return getOriginExpr()->getPlacementArg(Index); |
||
| 1062 | } |
||
| 1063 | |||
| 1064 | Kind getKind() const override { return CE_CXXAllocator; } |
||
| 1065 | StringRef getKindAsString() const override { return "CXXAllocatorCall"; } |
||
| 1066 | |||
| 1067 | static bool classof(const CallEvent *CE) { |
||
| 1068 | return CE->getKind() == CE_CXXAllocator; |
||
| 1069 | } |
||
| 1070 | }; |
||
| 1071 | |||
| 1072 | /// Represents the memory deallocation call in a C++ delete-expression. |
||
| 1073 | /// |
||
| 1074 | /// This is a call to "operator delete". |
||
| 1075 | // FIXME: CXXDeleteExpr isn't present for custom delete operators, or even for |
||
| 1076 | // some those that are in the standard library, like the no-throw or align_val |
||
| 1077 | // versions. |
||
| 1078 | // Some pointers: |
||
| 1079 | // http://lists.llvm.org/pipermail/cfe-dev/2020-April/065080.html |
||
| 1080 | // clang/test/Analysis/cxx-dynamic-memory-analysis-order.cpp |
||
| 1081 | // clang/unittests/StaticAnalyzer/CallEventTest.cpp |
||
| 1082 | class CXXDeallocatorCall : public AnyFunctionCall { |
||
| 1083 | friend class CallEventManager; |
||
| 1084 | |||
| 1085 | protected: |
||
| 1086 | CXXDeallocatorCall(const CXXDeleteExpr *E, ProgramStateRef St, |
||
| 1087 | const LocationContext *LCtx) |
||
| 1088 | : AnyFunctionCall(E, St, LCtx) {} |
||
| 1089 | CXXDeallocatorCall(const CXXDeallocatorCall &Other) = default; |
||
| 1090 | |||
| 1091 | void cloneTo(void *Dest) const override { |
||
| 1092 | new (Dest) CXXDeallocatorCall(*this); |
||
| 1093 | } |
||
| 1094 | |||
| 1095 | public: |
||
| 1096 | const CXXDeleteExpr *getOriginExpr() const override { |
||
| 1097 | return cast<CXXDeleteExpr>(AnyFunctionCall::getOriginExpr()); |
||
| 1098 | } |
||
| 1099 | |||
| 1100 | const FunctionDecl *getDecl() const override { |
||
| 1101 | return getOriginExpr()->getOperatorDelete(); |
||
| 1102 | } |
||
| 1103 | |||
| 1104 | unsigned getNumArgs() const override { return getDecl()->getNumParams(); } |
||
| 1105 | |||
| 1106 | const Expr *getArgExpr(unsigned Index) const override { |
||
| 1107 | // CXXDeleteExpr's only have a single argument. |
||
| 1108 | return getOriginExpr()->getArgument(); |
||
| 1109 | } |
||
| 1110 | |||
| 1111 | Kind getKind() const override { return CE_CXXDeallocator; } |
||
| 1112 | StringRef getKindAsString() const override { return "CXXDeallocatorCall"; } |
||
| 1113 | |||
| 1114 | static bool classof(const CallEvent *CE) { |
||
| 1115 | return CE->getKind() == CE_CXXDeallocator; |
||
| 1116 | } |
||
| 1117 | }; |
||
| 1118 | |||
| 1119 | /// Represents the ways an Objective-C message send can occur. |
||
| 1120 | // |
||
| 1121 | // Note to maintainers: OCM_Message should always be last, since it does not |
||
| 1122 | // need to fit in the Data field's low bits. |
||
| 1123 | enum ObjCMessageKind { |
||
| 1124 | OCM_PropertyAccess, |
||
| 1125 | OCM_Subscript, |
||
| 1126 | OCM_Message |
||
| 1127 | }; |
||
| 1128 | |||
| 1129 | /// Represents any expression that calls an Objective-C method. |
||
| 1130 | /// |
||
| 1131 | /// This includes all of the kinds listed in ObjCMessageKind. |
||
| 1132 | class ObjCMethodCall : public CallEvent { |
||
| 1133 | friend class CallEventManager; |
||
| 1134 | |||
| 1135 | const PseudoObjectExpr *getContainingPseudoObjectExpr() const; |
||
| 1136 | |||
| 1137 | protected: |
||
| 1138 | ObjCMethodCall(const ObjCMessageExpr *Msg, ProgramStateRef St, |
||
| 1139 | const LocationContext *LCtx) |
||
| 1140 | : CallEvent(Msg, St, LCtx) { |
||
| 1141 | Data = nullptr; |
||
| 1142 | } |
||
| 1143 | |||
| 1144 | ObjCMethodCall(const ObjCMethodCall &Other) = default; |
||
| 1145 | |||
| 1146 | void cloneTo(void *Dest) const override { new (Dest) ObjCMethodCall(*this); } |
||
| 1147 | |||
| 1148 | void getExtraInvalidatedValues(ValueList &Values, |
||
| 1149 | RegionAndSymbolInvalidationTraits *ETraits) const override; |
||
| 1150 | |||
| 1151 | /// Check if the selector may have multiple definitions (may have overrides). |
||
| 1152 | virtual bool canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl, |
||
| 1153 | Selector Sel) const; |
||
| 1154 | |||
| 1155 | public: |
||
| 1156 | const ObjCMessageExpr *getOriginExpr() const override { |
||
| 1157 | return cast<ObjCMessageExpr>(CallEvent::getOriginExpr()); |
||
| 1158 | } |
||
| 1159 | |||
| 1160 | const ObjCMethodDecl *getDecl() const override { |
||
| 1161 | return getOriginExpr()->getMethodDecl(); |
||
| 1162 | } |
||
| 1163 | |||
| 1164 | unsigned getNumArgs() const override { |
||
| 1165 | return getOriginExpr()->getNumArgs(); |
||
| 1166 | } |
||
| 1167 | |||
| 1168 | const Expr *getArgExpr(unsigned Index) const override { |
||
| 1169 | return getOriginExpr()->getArg(Index); |
||
| 1170 | } |
||
| 1171 | |||
| 1172 | bool isInstanceMessage() const { |
||
| 1173 | return getOriginExpr()->isInstanceMessage(); |
||
| 1174 | } |
||
| 1175 | |||
| 1176 | ObjCMethodFamily getMethodFamily() const { |
||
| 1177 | return getOriginExpr()->getMethodFamily(); |
||
| 1178 | } |
||
| 1179 | |||
| 1180 | Selector getSelector() const { |
||
| 1181 | return getOriginExpr()->getSelector(); |
||
| 1182 | } |
||
| 1183 | |||
| 1184 | SourceRange getSourceRange() const override; |
||
| 1185 | |||
| 1186 | /// Returns the value of the receiver at the time of this call. |
||
| 1187 | SVal getReceiverSVal() const; |
||
| 1188 | |||
| 1189 | /// Get the interface for the receiver. |
||
| 1190 | /// |
||
| 1191 | /// This works whether this is an instance message or a class message. |
||
| 1192 | /// However, it currently just uses the static type of the receiver. |
||
| 1193 | const ObjCInterfaceDecl *getReceiverInterface() const { |
||
| 1194 | return getOriginExpr()->getReceiverInterface(); |
||
| 1195 | } |
||
| 1196 | |||
| 1197 | /// Checks if the receiver refers to 'self' or 'super'. |
||
| 1198 | bool isReceiverSelfOrSuper() const; |
||
| 1199 | |||
| 1200 | /// Returns how the message was written in the source (property access, |
||
| 1201 | /// subscript, or explicit message send). |
||
| 1202 | ObjCMessageKind getMessageKind() const; |
||
| 1203 | |||
| 1204 | /// Returns true if this property access or subscript is a setter (has the |
||
| 1205 | /// form of an assignment). |
||
| 1206 | bool isSetter() const { |
||
| 1207 | switch (getMessageKind()) { |
||
| 1208 | case OCM_Message: |
||
| 1209 | llvm_unreachable("This is not a pseudo-object access!"); |
||
| 1210 | case OCM_PropertyAccess: |
||
| 1211 | return getNumArgs() > 0; |
||
| 1212 | case OCM_Subscript: |
||
| 1213 | return getNumArgs() > 1; |
||
| 1214 | } |
||
| 1215 | llvm_unreachable("Unknown message kind"); |
||
| 1216 | } |
||
| 1217 | |||
| 1218 | // Returns the property accessed by this method, either explicitly via |
||
| 1219 | // property syntax or implicitly via a getter or setter method. Returns |
||
| 1220 | // nullptr if the call is not a prooperty access. |
||
| 1221 | const ObjCPropertyDecl *getAccessedProperty() const; |
||
| 1222 | |||
| 1223 | RuntimeDefinition getRuntimeDefinition() const override; |
||
| 1224 | |||
| 1225 | bool argumentsMayEscape() const override; |
||
| 1226 | |||
| 1227 | void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, |
||
| 1228 | BindingsTy &Bindings) const override; |
||
| 1229 | |||
| 1230 | ArrayRef<ParmVarDecl*> parameters() const override; |
||
| 1231 | |||
| 1232 | Kind getKind() const override { return CE_ObjCMessage; } |
||
| 1233 | StringRef getKindAsString() const override { return "ObjCMethodCall"; } |
||
| 1234 | |||
| 1235 | static bool classof(const CallEvent *CA) { |
||
| 1236 | return CA->getKind() == CE_ObjCMessage; |
||
| 1237 | } |
||
| 1238 | }; |
||
| 1239 | |||
| 1240 | /// Manages the lifetime of CallEvent objects. |
||
| 1241 | /// |
||
| 1242 | /// CallEventManager provides a way to create arbitrary CallEvents "on the |
||
| 1243 | /// stack" as if they were value objects by keeping a cache of CallEvent-sized |
||
| 1244 | /// memory blocks. The CallEvents created by CallEventManager are only valid |
||
| 1245 | /// for the lifetime of the OwnedCallEvent that holds them; right now these |
||
| 1246 | /// objects cannot be copied and ownership cannot be transferred. |
||
| 1247 | class CallEventManager { |
||
| 1248 | friend class CallEvent; |
||
| 1249 | |||
| 1250 | llvm::BumpPtrAllocator &Alloc; |
||
| 1251 | SmallVector<void *, 8> Cache; |
||
| 1252 | |||
| 1253 | using CallEventTemplateTy = SimpleFunctionCall; |
||
| 1254 | |||
| 1255 | void reclaim(const void *Memory) { |
||
| 1256 | Cache.push_back(const_cast<void *>(Memory)); |
||
| 1257 | } |
||
| 1258 | |||
| 1259 | /// Returns memory that can be initialized as a CallEvent. |
||
| 1260 | void *allocate() { |
||
| 1261 | if (Cache.empty()) |
||
| 1262 | return Alloc.Allocate<CallEventTemplateTy>(); |
||
| 1263 | else |
||
| 1264 | return Cache.pop_back_val(); |
||
| 1265 | } |
||
| 1266 | |||
| 1267 | template <typename T, typename Arg> |
||
| 1268 | T *create(Arg A, ProgramStateRef St, const LocationContext *LCtx) { |
||
| 1269 | static_assert(sizeof(T) == sizeof(CallEventTemplateTy), |
||
| 1270 | "CallEvent subclasses are not all the same size"); |
||
| 1271 | return new (allocate()) T(A, St, LCtx); |
||
| 1272 | } |
||
| 1273 | |||
| 1274 | template <typename T, typename Arg1, typename Arg2> |
||
| 1275 | T *create(Arg1 A1, Arg2 A2, ProgramStateRef St, const LocationContext *LCtx) { |
||
| 1276 | static_assert(sizeof(T) == sizeof(CallEventTemplateTy), |
||
| 1277 | "CallEvent subclasses are not all the same size"); |
||
| 1278 | return new (allocate()) T(A1, A2, St, LCtx); |
||
| 1279 | } |
||
| 1280 | |||
| 1281 | template <typename T, typename Arg1, typename Arg2, typename Arg3> |
||
| 1282 | T *create(Arg1 A1, Arg2 A2, Arg3 A3, ProgramStateRef St, |
||
| 1283 | const LocationContext *LCtx) { |
||
| 1284 | static_assert(sizeof(T) == sizeof(CallEventTemplateTy), |
||
| 1285 | "CallEvent subclasses are not all the same size"); |
||
| 1286 | return new (allocate()) T(A1, A2, A3, St, LCtx); |
||
| 1287 | } |
||
| 1288 | |||
| 1289 | template <typename T, typename Arg1, typename Arg2, typename Arg3, |
||
| 1290 | typename Arg4> |
||
| 1291 | T *create(Arg1 A1, Arg2 A2, Arg3 A3, Arg4 A4, ProgramStateRef St, |
||
| 1292 | const LocationContext *LCtx) { |
||
| 1293 | static_assert(sizeof(T) == sizeof(CallEventTemplateTy), |
||
| 1294 | "CallEvent subclasses are not all the same size"); |
||
| 1295 | return new (allocate()) T(A1, A2, A3, A4, St, LCtx); |
||
| 1296 | } |
||
| 1297 | |||
| 1298 | public: |
||
| 1299 | CallEventManager(llvm::BumpPtrAllocator &alloc) : Alloc(alloc) {} |
||
| 1300 | |||
| 1301 | /// Gets an outside caller given a callee context. |
||
| 1302 | CallEventRef<> |
||
| 1303 | getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State); |
||
| 1304 | |||
| 1305 | /// Gets a call event for a function call, Objective-C method call, |
||
| 1306 | /// a 'new', or a 'delete' call. |
||
| 1307 | CallEventRef<> |
||
| 1308 | getCall(const Stmt *S, ProgramStateRef State, |
||
| 1309 | const LocationContext *LC); |
||
| 1310 | |||
| 1311 | CallEventRef<> |
||
| 1312 | getSimpleCall(const CallExpr *E, ProgramStateRef State, |
||
| 1313 | const LocationContext *LCtx); |
||
| 1314 | |||
| 1315 | CallEventRef<ObjCMethodCall> |
||
| 1316 | getObjCMethodCall(const ObjCMessageExpr *E, ProgramStateRef State, |
||
| 1317 | const LocationContext *LCtx) { |
||
| 1318 | return create<ObjCMethodCall>(E, State, LCtx); |
||
| 1319 | } |
||
| 1320 | |||
| 1321 | CallEventRef<CXXConstructorCall> |
||
| 1322 | getCXXConstructorCall(const CXXConstructExpr *E, const MemRegion *Target, |
||
| 1323 | ProgramStateRef State, const LocationContext *LCtx) { |
||
| 1324 | return create<CXXConstructorCall>(E, Target, State, LCtx); |
||
| 1325 | } |
||
| 1326 | |||
| 1327 | CallEventRef<CXXInheritedConstructorCall> |
||
| 1328 | getCXXInheritedConstructorCall(const CXXInheritedCtorInitExpr *E, |
||
| 1329 | const MemRegion *Target, ProgramStateRef State, |
||
| 1330 | const LocationContext *LCtx) { |
||
| 1331 | return create<CXXInheritedConstructorCall>(E, Target, State, LCtx); |
||
| 1332 | } |
||
| 1333 | |||
| 1334 | CallEventRef<CXXDestructorCall> |
||
| 1335 | getCXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger, |
||
| 1336 | const MemRegion *Target, bool IsBase, |
||
| 1337 | ProgramStateRef State, const LocationContext *LCtx) { |
||
| 1338 | return create<CXXDestructorCall>(DD, Trigger, Target, IsBase, State, LCtx); |
||
| 1339 | } |
||
| 1340 | |||
| 1341 | CallEventRef<CXXAllocatorCall> |
||
| 1342 | getCXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef State, |
||
| 1343 | const LocationContext *LCtx) { |
||
| 1344 | return create<CXXAllocatorCall>(E, State, LCtx); |
||
| 1345 | } |
||
| 1346 | |||
| 1347 | CallEventRef<CXXDeallocatorCall> |
||
| 1348 | getCXXDeallocatorCall(const CXXDeleteExpr *E, ProgramStateRef State, |
||
| 1349 | const LocationContext *LCtx) { |
||
| 1350 | return create<CXXDeallocatorCall>(E, State, LCtx); |
||
| 1351 | } |
||
| 1352 | }; |
||
| 1353 | |||
| 1354 | template <typename T> |
||
| 1355 | CallEventRef<T> CallEvent::cloneWithState(ProgramStateRef NewState) const { |
||
| 1356 | assert(isa<T>(*this) && "Cloning to unrelated type"); |
||
| 1357 | static_assert(sizeof(T) == sizeof(CallEvent), |
||
| 1358 | "Subclasses may not add fields"); |
||
| 1359 | |||
| 1360 | if (NewState == State) |
||
| 1361 | return cast<T>(this); |
||
| 1362 | |||
| 1363 | CallEventManager &Mgr = State->getStateManager().getCallEventManager(); |
||
| 1364 | T *Copy = static_cast<T *>(Mgr.allocate()); |
||
| 1365 | cloneTo(Copy); |
||
| 1366 | assert(Copy->getKind() == this->getKind() && "Bad copy"); |
||
| 1367 | |||
| 1368 | Copy->State = NewState; |
||
| 1369 | return Copy; |
||
| 1370 | } |
||
| 1371 | |||
| 1372 | inline void CallEvent::Release() const { |
||
| 1373 | assert(RefCount > 0 && "Reference count is already zero."); |
||
| 1374 | --RefCount; |
||
| 1375 | |||
| 1376 | if (RefCount > 0) |
||
| 1377 | return; |
||
| 1378 | |||
| 1379 | CallEventManager &Mgr = State->getStateManager().getCallEventManager(); |
||
| 1380 | Mgr.reclaim(this); |
||
| 1381 | |||
| 1382 | this->~CallEvent(); |
||
| 1383 | } |
||
| 1384 | |||
| 1385 | } // namespace ento |
||
| 1386 | |||
| 1387 | } // namespace clang |
||
| 1388 | |||
| 1389 | namespace llvm { |
||
| 1390 | |||
| 1391 | // Support isa<>, cast<>, and dyn_cast<> for CallEventRef. |
||
| 1392 | template<class T> struct simplify_type< clang::ento::CallEventRef<T>> { |
||
| 1393 | using SimpleType = const T *; |
||
| 1394 | |||
| 1395 | static SimpleType |
||
| 1396 | getSimplifiedValue(clang::ento::CallEventRef<T> Val) { |
||
| 1397 | return Val.get(); |
||
| 1398 | } |
||
| 1399 | }; |
||
| 1400 | |||
| 1401 | } // namespace llvm |
||
| 1402 | |||
| 1403 | #endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLEVENT_H |