summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/SymbolManager.cpp
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2011-08-11 16:43:28 +0000
committerAnna Zaks <ganna@apple.com>2011-08-11 16:43:28 +0000
commit22a9d0f3165503df3da45475cd06a3c87d38f7b2 (patch)
tree89a9babb197aa654c1e061f96fd28920b2150544 /clang/lib/StaticAnalyzer/Core/SymbolManager.cpp
parent1542d5a00ae870cd6996496fac29f8818b042efd (diff)
downloadbcm5719-llvm-22a9d0f3165503df3da45475cd06a3c87d38f7b2.tar.gz
bcm5719-llvm-22a9d0f3165503df3da45475cd06a3c87d38f7b2.zip
Analyzer Core: Adding support for user-defined symbol dependencies. (For example, the allocated resource symbol only needs to be freed if no error has been returned by the allocator, so a checker might want to make the lifespan of the error code symbol depend on the allocated resource symbol.) Note, by default, the map that holds the dependencies will get destroyed along with the SymbolManager at the end of function exploration.
llvm-svn: 137309
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/SymbolManager.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/SymbolManager.cpp31
1 files changed, 30 insertions, 1 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/SymbolManager.cpp b/clang/lib/StaticAnalyzer/Core/SymbolManager.cpp
index 6d90d19f9ed..b4a0d69c008 100644
--- a/clang/lib/StaticAnalyzer/Core/SymbolManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/SymbolManager.cpp
@@ -248,9 +248,36 @@ bool SymbolManager::canSymbolicate(QualType T) {
return false;
}
+void SymbolManager::addSymbolDependency(const SymbolRef Primary,
+ const SymbolRef Dependent) {
+ SymbolDependencies[Primary].push_back(Dependent);
+}
+
+void SymbolManager::removeSymbolDependencies(const SymbolRef Primary) {
+ SymbolDependencies.erase(Primary);
+}
+
+const SymbolRefSmallVectorTy *SymbolManager::getDependentSymbols(
+ const SymbolRef Primary) {
+ SymbolDependTy::const_iterator I = SymbolDependencies.find(Primary);
+ if (I == SymbolDependencies.end())
+ return 0;
+ return &I->second;
+}
+
+void SymbolReaper::markDependentsLive(SymbolRef sym) {
+ if (const SymbolRefSmallVectorTy *Deps = SymMgr.getDependentSymbols(sym)) {
+ for (SymbolRefSmallVectorTy::const_iterator I = Deps->begin(),
+ E = Deps->end(); I != E; ++I) {
+ markLive(*I);
+ }
+ }
+}
+
void SymbolReaper::markLive(SymbolRef sym) {
TheLiving.insert(sym);
TheDead.erase(sym);
+ markDependentsLive(sym);
}
void SymbolReaper::markLive(const MemRegion *region) {
@@ -299,8 +326,10 @@ bool SymbolReaper::isLiveRegion(const MemRegion *MR) {
}
bool SymbolReaper::isLive(SymbolRef sym) {
- if (TheLiving.count(sym))
+ if (TheLiving.count(sym)) {
+ markDependentsLive(sym);
return true;
+ }
if (const SymbolDerived *derived = dyn_cast<SymbolDerived>(sym)) {
if (isLive(derived->getParentSymbol())) {
OpenPOWER on IntegriCloud