Index: include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h @@ -22,6 +22,8 @@ namespace clang { namespace ento { +class MemRegion; + /// \brief Symbolic value. These values used to capture symbolic execution of /// the program. class SymExpr : public llvm::FoldingSetNode { @@ -76,6 +78,7 @@ static symbol_iterator symbol_end() { return symbol_iterator(); } unsigned computeComplexity() const; + const MemRegion *getOriginRegion() const; }; typedef const SymExpr *SymbolRef; Index: lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp +++ lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp @@ -315,15 +315,7 @@ /// Returns nullptr if the instance symbol cannot be found. const ObjCIvarRegion * ObjCDeallocChecker::getIvarRegionForIvarSymbol(SymbolRef IvarSym) const { - const MemRegion *RegionLoadedFrom = nullptr; - if (auto *DerivedSym = dyn_cast(IvarSym)) - RegionLoadedFrom = DerivedSym->getRegion(); - else if (auto *RegionSym = dyn_cast(IvarSym)) - RegionLoadedFrom = RegionSym->getRegion(); - else - return nullptr; - - return dyn_cast(RegionLoadedFrom); + return dyn_cast_or_null(IvarSym->getOriginRegion()); } /// Given a symbol for an ivar, return a symbol for the instance containing Index: lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp +++ lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp @@ -2833,14 +2833,6 @@ C.addTransition(State); } -static bool wasLoadedFromIvar(SymbolRef Sym) { - if (auto DerivedVal = dyn_cast(Sym)) - return isa(DerivedVal->getRegion()); - if (auto RegionVal = dyn_cast(Sym)) - return isa(RegionVal->getRegion()); - return false; -} - void RetainCountChecker::checkPostStmt(const ObjCIvarRefExpr *IRE, CheckerContext &C) const { Optional IVarLoc = C.getSVal(IRE).getAs(); @@ -2849,7 +2841,7 @@ ProgramStateRef State = C.getState(); SymbolRef Sym = State->getSVal(*IVarLoc).getAsSymbol(); - if (!Sym || !wasLoadedFromIvar(Sym)) + if (!Sym || !dyn_cast_or_null(Sym->getOriginRegion())) return; // Accessing an ivar directly is unusual. If we've done that, be more Index: lib/StaticAnalyzer/Core/SymbolManager.cpp =================================================================== --- lib/StaticAnalyzer/Core/SymbolManager.cpp +++ lib/StaticAnalyzer/Core/SymbolManager.cpp @@ -147,6 +147,14 @@ return R; } +const MemRegion *SymExpr::getOriginRegion() const { + if (const SymbolRegionValue *SRV = dyn_cast(this)) + return SRV->getRegion(); + else if (const SymbolDerived *SD = dyn_cast(this)) + return SD->getRegion(); + return nullptr; +} + const SymbolRegionValue* SymbolManager::getRegionValueSymbol(const TypedValueRegion* R) { llvm::FoldingSetNodeID profile;