summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h14
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h2
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp10
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp10
4 files changed, 18 insertions, 18 deletions
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h
index be9646ba6a6..18bc60754b8 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h
+++ b/clang/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,18 @@ public:
static symbol_iterator symbol_end() { return symbol_iterator(); }
unsigned computeComplexity() const;
+
+ /// \brief Find the region from which this symbol originates.
+ ///
+ /// Whenever the symbol was constructed to denote an unknown value of
+ /// a certain memory region, return this region. This method
+ /// allows checkers to make decisions depending on the origin of the symbol.
+ /// Symbol classes for which the origin region is known include
+ /// SymbolRegionValue which denotes the value of the region before
+ /// the beginning of the analysis, and SymbolDerived which denotes the value
+ /// of a certain memory region after its super region (a memory space or
+ /// a larger record region) is default-bound with a certain symbol.
+ virtual const MemRegion *getOriginRegion() const { return nullptr; }
};
typedef const SymExpr *SymbolRef;
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
index 30481ea3913..087430583e0 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
@@ -58,6 +58,7 @@ public:
}
void dumpToStream(raw_ostream &os) const override;
+ const MemRegion *getOriginRegion() const override { return getRegion(); }
QualType getType() const override;
@@ -127,6 +128,7 @@ public:
QualType getType() const override;
void dumpToStream(raw_ostream &os) const override;
+ const MemRegion *getOriginRegion() const override { return getRegion(); }
static void Profile(llvm::FoldingSetNodeID& profile, SymbolRef parent,
const TypedValueRegion *r) {
diff --git a/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp b/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
index 50915f399a1..9e863e79e41 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
@@ -315,15 +315,7 @@ void ObjCDeallocChecker::checkBeginFunction(
/// 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
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index c344bb17093..b646127cfae 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -2833,14 +2833,6 @@ void RetainCountChecker::checkPostStmt(const ObjCBoxedExpr *Ex,
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>();
@@ -2849,7 +2841,7 @@ void RetainCountChecker::checkPostStmt(const ObjCIvarRefExpr *IRE,
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
OpenPOWER on IntegriCloud