diff options
Diffstat (limited to 'clang/lib/StaticAnalyzer')
4 files changed, 30 insertions, 17 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp index e1f9a77..955b8d1 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp @@ -385,6 +385,10 @@ public: if (RTC.isUnretained(RetValue->getType())) return; } + if (retainsRet && *retainsRet) { + CreateOrCopyFnCall.insert(RetValue); + return; + } if (auto *CE = dyn_cast<CallExpr>(RetValue)) { auto *Callee = CE->getDirectCallee(); if (!Callee || !isCreateOrCopyFunction(Callee)) diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp index 180056c..06ba015 100644 --- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp +++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -1254,6 +1254,15 @@ template <> struct DenseMapInfo<PrivateMethodKey> { }; } // end namespace llvm +// NOTE: This cache is a "global" variable, and it is cleared by +// CallEventManager's constructor so we do not keep old entries when +// loading/unloading ASTs. If we are worried about concurrency, we may need to +// revisit this someday. In terms of memory, this table stays around until clang +// quits, which also may be bad if we need to release memory. +using PrivateMethodCacheTy = + llvm::DenseMap<PrivateMethodKey, std::optional<const ObjCMethodDecl *>>; +static PrivateMethodCacheTy PrivateMethodCache; + static const ObjCMethodDecl * lookupRuntimeDefinition(const ObjCInterfaceDecl *Interface, Selector LookupSelector, bool InstanceMethod) { @@ -1262,21 +1271,8 @@ lookupRuntimeDefinition(const ObjCInterfaceDecl *Interface, // that repeated queries on the same ObjCIntefaceDecl and Selector // don't incur the same cost. On some test cases, we can see the // same query being issued thousands of times. - // - // NOTE: This cache is essentially a "global" variable, but it - // only gets lazily created when we get here. The value of the - // cache probably comes from it being global across ExprEngines, - // where the same queries may get issued. If we are worried about - // concurrency, or possibly loading/unloading ASTs, etc., we may - // need to revisit this someday. In terms of memory, this table - // stays around until clang quits, which also may be bad if we - // need to release memory. - using PrivateMethodCache = - llvm::DenseMap<PrivateMethodKey, std::optional<const ObjCMethodDecl *>>; - - static PrivateMethodCache PMC; std::optional<const ObjCMethodDecl *> &Val = - PMC[{Interface, LookupSelector, InstanceMethod}]; + PrivateMethodCache[{Interface, LookupSelector, InstanceMethod}]; // Query lookupPrivateMethod() if the cache does not hit. if (!Val) { @@ -1422,6 +1418,13 @@ void ObjCMethodCall::getInitialStackFrameContents( } } +CallEventManager::CallEventManager(llvm::BumpPtrAllocator &alloc) + : Alloc(alloc) { + // Clear the method cache to avoid hits when multiple AST are loaded/unloaded + // within a single process. This can happen with unit tests, for instance. + PrivateMethodCache.clear(); +} + CallEventRef<> CallEventManager::getSimpleCall(const CallExpr *CE, ProgramStateRef State, const LocationContext *LCtx, diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index 8e9d6fe..af0ef52 100644 --- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -2658,14 +2658,20 @@ RegionStoreManager::bindArray(LimitedRegionBindingsConstRef B, return bindAggregate(B, R, V); } - // Handle lazy compound values. + // FIXME Single value constant should have been handled before this call to + // bindArray. This is only a hotfix to not crash. + if (Init.isConstant()) + return bindAggregate(B, R, Init); + if (std::optional LCV = Init.getAs<nonloc::LazyCompoundVal>()) { if (std::optional NewB = tryBindSmallArray(B, R, AT, *LCV)) return *NewB; - return bindAggregate(B, R, Init); } + if (isa<nonloc::SymbolVal>(Init)) + return bindAggregate(B, R, Init); + if (Init.isUnknown()) return bindAggregate(B, R, UnknownVal()); diff --git a/clang/lib/StaticAnalyzer/Core/Store.cpp b/clang/lib/StaticAnalyzer/Core/Store.cpp index 971e6bc..b609f36 100644 --- a/clang/lib/StaticAnalyzer/Core/Store.cpp +++ b/clang/lib/StaticAnalyzer/Core/Store.cpp @@ -210,7 +210,7 @@ std::optional<const MemRegion *> StoreManager::castRegion(const MemRegion *R, // Is the offset a multiple of the size? If so, we can layer the // ElementRegion (with elementType == PointeeTy) directly on top of // the base region. - if (off % pointeeTySize == 0) { + if (off.isMultipleOf(pointeeTySize)) { newIndex = off / pointeeTySize; newSuperR = baseR; } |