NoQ created this revision. NoQ added a reviewer: dcoughlin. NoQ added a subscriber: cfe-commits.
Or, more importantly, tell the users that there's a way to discover the region, value of which - at some moment of time - the symbol was introduced to represent. Idea proposed by Devin Coughlin. Right now this is a simple code de-duplication, but in fact maybe it should be extended to support SymbolMetadata, SymbolExtent, and maybe, even more importantly, SymbolConjured (if the latter is created during invalidation of a region, *and* the symbol's structure is modified to remember that region - which i think is a useful idea, but that's another story; there's not much we could do for conjured-return-value symbols, even though sometimes even they should probably be tied to temporary object regions). http://reviews.llvm.org/D22242 Files: include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp lib/StaticAnalyzer/Core/SymbolManager.cpp 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<SymbolRegionValue>(this)) + return SRV->getRegion(); + else if (const SymbolDerived *SD = dyn_cast<SymbolDerived>(this)) + return SD->getRegion(); + return nullptr; +} + const SymbolRegionValue* SymbolManager::getRegionValueSymbol(const TypedValueRegion* R) { llvm::FoldingSetNodeID profile; Index: lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp +++ lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp @@ -2833,23 +2833,15 @@ C.addTransition(State); } -static bool wasLoadedFromIvar(SymbolRef Sym) { - if (auto DerivedVal = dyn_cast<SymbolDerived>(Sym)) - return isa<ObjCIvarRegion>(DerivedVal->getRegion()); - if (auto RegionVal = dyn_cast<SymbolRegionValue>(Sym)) - return isa<ObjCIvarRegion>(RegionVal->getRegion()); - return false; -} - void RetainCountChecker::checkPostStmt(const ObjCIvarRefExpr *IRE, CheckerContext &C) const { Optional<Loc> IVarLoc = C.getSVal(IRE).getAs<Loc>(); if (!IVarLoc) return; ProgramStateRef State = C.getState(); SymbolRef Sym = State->getSVal(*IVarLoc).getAsSymbol(); - if (!Sym || !wasLoadedFromIvar(Sym)) + if (!Sym || !dyn_cast_or_null<ObjCIvarRegion>(Sym->getOriginRegion())) return; // Accessing an ivar directly is unusual. If we've done that, be more 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<SymbolDerived>(IvarSym)) - RegionLoadedFrom = DerivedSym->getRegion(); - else if (auto *RegionSym = dyn_cast<SymbolRegionValue>(IvarSym)) - RegionLoadedFrom = RegionSym->getRegion(); - else - return nullptr; - - return dyn_cast<ObjCIvarRegion>(RegionLoadedFrom); + return dyn_cast_or_null<ObjCIvarRegion>(IvarSym->getOriginRegion()); } /// Given a symbol for an ivar, return a symbol for the instance containing 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/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<SymbolRegionValue>(this)) + return SRV->getRegion(); + else if (const SymbolDerived *SD = dyn_cast<SymbolDerived>(this)) + return SD->getRegion(); + return nullptr; +} + const SymbolRegionValue* SymbolManager::getRegionValueSymbol(const TypedValueRegion* R) { llvm::FoldingSetNodeID profile; Index: lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp +++ lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp @@ -2833,23 +2833,15 @@ C.addTransition(State); } -static bool wasLoadedFromIvar(SymbolRef Sym) { - if (auto DerivedVal = dyn_cast<SymbolDerived>(Sym)) - return isa<ObjCIvarRegion>(DerivedVal->getRegion()); - if (auto RegionVal = dyn_cast<SymbolRegionValue>(Sym)) - return isa<ObjCIvarRegion>(RegionVal->getRegion()); - return false; -} - void RetainCountChecker::checkPostStmt(const ObjCIvarRefExpr *IRE, CheckerContext &C) const { Optional<Loc> IVarLoc = C.getSVal(IRE).getAs<Loc>(); if (!IVarLoc) return; ProgramStateRef State = C.getState(); SymbolRef Sym = State->getSVal(*IVarLoc).getAsSymbol(); - if (!Sym || !wasLoadedFromIvar(Sym)) + if (!Sym || !dyn_cast_or_null<ObjCIvarRegion>(Sym->getOriginRegion())) return; // Accessing an ivar directly is unusual. If we've done that, be more 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<SymbolDerived>(IvarSym)) - RegionLoadedFrom = DerivedSym->getRegion(); - else if (auto *RegionSym = dyn_cast<SymbolRegionValue>(IvarSym)) - RegionLoadedFrom = RegionSym->getRegion(); - else - return nullptr; - - return dyn_cast<ObjCIvarRegion>(RegionLoadedFrom); + return dyn_cast_or_null<ObjCIvarRegion>(IvarSym->getOriginRegion()); } /// Given a symbol for an ivar, return a symbol for the instance containing 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;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits