diff options
author | Andrei Karas <akaras@inbox.ru> | 2015-06-25 00:32:45 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2015-06-25 00:33:08 +0300 |
commit | 498d31aa2baf69aabf29f561888f55224058b963 (patch) | |
tree | 0e55a72066fdd2a8fd4330476b4cff773fa550ae /src/analysis/analysis.cpp | |
parent | 92d59a9cc286433e5f6b36c25039bd0289fb0946 (diff) | |
download | paranucker-498d31aa2baf69aabf29f561888f55224058b963.tar.gz paranucker-498d31aa2baf69aabf29f561888f55224058b963.tar.bz2 paranucker-498d31aa2baf69aabf29f561888f55224058b963.tar.xz paranucker-498d31aa2baf69aabf29f561888f55224058b963.zip |
Fix some false positives and other issues related to linked vars.
Add reverse linked vars map.
Diffstat (limited to 'src/analysis/analysis.cpp')
-rw-r--r-- | src/analysis/analysis.cpp | 64 |
1 files changed, 43 insertions, 21 deletions
diff --git a/src/analysis/analysis.cpp b/src/analysis/analysis.cpp index d17a46a..91fec0d 100644 --- a/src/analysis/analysis.cpp +++ b/src/analysis/analysis.cpp @@ -73,31 +73,50 @@ void addCheckNullVars(WalkItem &wi, WalkItem &wo) } } -void removeCheckNullVarsSet(WalkItem &wi, std::set<std::string> &vars) +void removeCheckNullVar(WalkItem &wi, std::string str) { - FOR_EACH (std::set<std::string>::const_iterator, it, vars) + // found var for deletion + if (wi.checkNullVars.find(str) != wi.checkNullVars.end()) { - // found var for deletion - if (wi.checkNullVars.find(*it) != wi.checkNullVars.end()) - { - wi.checkNullVars.erase(*it); - } - if (wi.addNullVars.find(*it) != wi.addNullVars.end()) - { - wi.addNullVars.erase(*it); - } - StringMapSet::const_iterator it2 = wi.linkedVars.find(*it); - if (it2 != wi.linkedVars.end()) + wi.checkNullVars.erase(str); + } + if (wi.addNullVars.find(str) != wi.addNullVars.end()) + { + wi.addNullVars.erase(str); + } + StringMapSet::const_iterator it2 = wi.linkedVars.find(str); + if (it2 != wi.linkedVars.end()) + { + const StringSet &linked = (*it2).second; + FOR_EACH (StringSet::const_iterator, it3, linked) { - const StringSet &linked = (*it2).second; - FOR_EACH (StringSet::const_iterator, it3, linked) + if (wi.checkNullVars.find(*it3) != wi.checkNullVars.end()) + { + wi.checkNullVars.erase(*it3); + } + if (wi.addNullVars.find(*it3) != wi.addNullVars.end()) { - if (wi.checkNullVars.find(*it3) != wi.checkNullVars.end()) - { - wi.checkNullVars.erase(*it3); - } + wi.addNullVars.erase(*it3); } - wi.linkedVars.erase(*it); + } + //wi.linkedVars.erase(str); + } +} + +void removeCheckNullVarsSet(WalkItem &wi, std::set<std::string> &vars) +{ + FOR_EACH (std::set<std::string>::const_iterator, it, vars) + { + // remove var if need + removeCheckNullVar(wi, *it); + // if need remove some linked var, search it parent, + // and remove all linked vars for this parent + StringMap::const_iterator it3 = wi.linkedReverseVars.find(*it); + if (it3 != wi.linkedReverseVars.end()) + { + const std::string parent = (*it3).second; + //wi.linkedVars.erase(parent); + removeCheckNullVar(wi, parent); } } } @@ -109,6 +128,7 @@ void addLinkedVar(WalkItem &wi, if (wi.linkedVars.find(parent) == wi.linkedVars.end()) wi.linkedVars[parent] = std::set<std::string>(); wi.linkedVars[parent].insert(var); + wi.linkedReverseVars[var] = parent; } void startWalkTree(Node *node) @@ -132,8 +152,8 @@ void walkTree(Node *node, const WalkItem &wi, WalkItem &wo) addCheckNullVars(wo, wi2); addCheckNullVars(wi2, wi2); wi2.linkedVars = wo.linkedVars; + wi2.linkedReverseVars = wo.linkedReverseVars; wi2.addNullVars = wo.addNullVars; - wi2.linkedVars = wo.linkedVars; const bool isReturned = wo.isReturned; if (wo.stopWalking) @@ -155,12 +175,14 @@ void walkTree(Node *node, const WalkItem &wi, WalkItem &wo) wo2.checkNullVars = wi2.checkNullVars; wi2.isReturned = wi2.isReturned || wo2.isReturned; wi2.linkedVars = wo2.linkedVars; + wi2.linkedReverseVars = wo2.linkedReverseVars; wo2.stopWalking = false; } wo.removeNullVars = wi2.removeNullVars; wo.addNullVars = wi2.addNullVars; wo.isReturned = wo.isReturned || isReturned || wo2.isReturned; wo.linkedVars = wi2.linkedVars; + wo.linkedReverseVars = wi2.linkedReverseVars; if (command != Command::DumpNullPointers) Log::dumpWI(node, "walkTree out wo ", wo); |