diff options
author | Andrei Karas <akaras@inbox.ru> | 2015-07-04 17:43:29 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2015-07-04 17:43:29 +0300 |
commit | 4cde22214f0f91050c8e0e3b73de0f006fd6f3f6 (patch) | |
tree | c6b519de03cb3acf83ae2cb25e3f38ab3a4f0e5c /src | |
parent | 3f3568923589b2c5d8c269e623e7a8a3751011f1 (diff) | |
download | paranucker-4cde22214f0f91050c8e0e3b73de0f006fd6f3f6.tar.gz paranucker-4cde22214f0f91050c8e0e3b73de0f006fd6f3f6.tar.bz2 paranucker-4cde22214f0f91050c8e0e3b73de0f006fd6f3f6.tar.xz paranucker-4cde22214f0f91050c8e0e3b73de0f006fd6f3f6.zip |
Fix most issues with linked vars.
Diffstat (limited to 'src')
-rw-r--r-- | src/analysis/collections.cpp | 115 | ||||
-rw-r--r-- | src/analysis/collections.h | 2 | ||||
-rw-r--r-- | src/analysis/expression.cpp | 15 |
3 files changed, 99 insertions, 33 deletions
diff --git a/src/analysis/collections.cpp b/src/analysis/collections.cpp index 21c8ec1..50c4ff3 100644 --- a/src/analysis/collections.cpp +++ b/src/analysis/collections.cpp @@ -86,34 +86,55 @@ void removeNeedCheckNullVarsSetAll(WalkItem &wi, std::set<std::string> &vars) } } -// remove vars from checks for null pointer without linked vars -void removeNeedCheckNullVarsSet(WalkItem &wi, std::set<std::string> &vars) +void removeNeedCheckNullVarOnly(WalkItem &wi, const std::string &var) { - FOR_EACH (it, vars) + if (isIn(var, wi.needCheckNullVars)) { - if (isIn(it, wi.needCheckNullVars)) - { - wi.needCheckNullVars.erase(it); - } - if (isIn(it, wi.addNullVars)) - { - wi.addNullVars.erase(it); - } - auto it2 = wi.linkedVars.find(it); - if (it2 != wi.linkedVars.end()) + wi.needCheckNullVars.erase(var); + } + if (isIn(var, wi.addNullVars)) + { + wi.addNullVars.erase(var); + } + auto it2 = wi.linkedVars.find(var); + if (it2 != wi.linkedVars.end()) + { + const StringSet linked = (*it2).second; + std::string newParent = *(linked.begin()); + wi.linkedReverseVars.erase(newParent); + wi.linkedVars[newParent] = linked; + wi.linkedVars.erase(var); + wi.linkedVars[newParent].erase(newParent); + if (wi.linkedVars[newParent].empty()) { - const StringSet linked = (*it2).second; - std::string newParent = *(linked.begin()); - wi.linkedVars[newParent] = linked; - wi.linkedVars.erase(it); - wi.linkedVars[newParent].erase(newParent); + wi.linkedVars.erase(newParent); } - auto it3 = wi.linkedReverseVars.find(it); - if (it3 != wi.linkedReverseVars.end()) + else { - wi.linkedReverseVars.erase(it); + const StringSet &linked2 = wi.linkedVars[newParent]; + FOR_EACH (it3, linked2) + { + wi.linkedReverseVars[it3] = newParent; + } } } + if (isIn(var, wi.linkedReverseVars)) + { + std::string parent = wi.linkedReverseVars[var]; + wi.linkedVars[parent].erase(var); + if (wi.linkedVars[parent].empty()) + wi.linkedVars.erase(parent); + } + wi.linkedReverseVars.erase(var); +} + +// remove vars from checks for null pointer without linked vars +void removeNeedCheckNullVarsSet(WalkItem &wi, std::set<std::string> &vars) +{ + FOR_EACH (it, vars) + { + removeNeedCheckNullVarOnly(wi, it); + } } void addNullVar(WalkItem &wi, @@ -128,6 +149,7 @@ void addLinkedVar(WalkItem &wi, std::string parent, const std::string &var) { + //Log::log("add var\n"); if (isIn(parent, wi.addNullVars) || isIn(parent, wi.needCheckNullVars)) { @@ -151,6 +173,14 @@ void addLinkedVar(WalkItem &wi, } wi.knownVars.insert(var); + if (isIn(var, wi.linkedReverseVars)) + { + std::string oldParent = wi.linkedReverseVars[var]; + wi.linkedVars[oldParent].erase(var); + if (wi.linkedVars.empty()) + wi.linkedVars.erase(oldParent); + } + // found parent as already linked var. need change parent to real parent if (isIn(parent, wi.linkedReverseVars)) parent = wi.linkedReverseVars[parent]; @@ -158,6 +188,40 @@ void addLinkedVar(WalkItem &wi, wi.linkedVars[parent] = std::set<std::string>(); wi.linkedVars[parent].insert(var); wi.linkedReverseVars[var] = parent; + + // found what variable have linked vars to it. + // Need move all this vars to new parent. + if (isIn(var, wi.linkedVars)) + { + StringSet linked = wi.linkedVars[var]; + std::string newParent = *(linked.begin()); + wi.linkedReverseVars.erase(newParent); + wi.linkedVars[newParent] = linked; + wi.linkedVars.erase(var); + wi.linkedVars[newParent].erase(newParent); + if (wi.linkedVars[newParent].empty()) + { + wi.linkedVars.erase(newParent); + } + else + { + const StringSet &linked2 = wi.linkedVars[newParent]; + FOR_EACH (it3, linked2) + { + wi.linkedReverseVars[it3] = newParent; + } + } +/* + StringSet oldLinked = wi.linkedVars[var]; + wi.linkedVars.erase(var); + wi.linkedVars[parent].insert(oldLinked.begin(), + oldLinked.end()); + FOR_EACH (it, oldLinked) + { + wi.linkedReverseVars[it] = parent; + } +*/ + } } // merger two checked for null var sets @@ -276,4 +340,13 @@ void addKnownNonNullVarsWithLinked(WalkItem &wo, WalkItem &wi, std::set<std::str } } +void removeVar(WalkItem &wi, const std::string &var) +{ + wi.removeNullVars.insert(var); + wi.knownVars.erase(var); + wi.knownNullVars.erase(var); + wi.knownNonNullVars.erase(var); + removeNeedCheckNullVarOnly(wi, var); +} + } diff --git a/src/analysis/collections.h b/src/analysis/collections.h index 2911d33..738b8a8 100644 --- a/src/analysis/collections.h +++ b/src/analysis/collections.h @@ -74,6 +74,8 @@ namespace Analysis void addKnownNonNullVarsWithLinked(WalkItem &wo, WalkItem &wi, std::set<std::string> &vars); + + void removeVar(WalkItem &wi, const std::string &var); } #endif // ANALYSIS_COLLECTIONS_H diff --git a/src/analysis/expression.cpp b/src/analysis/expression.cpp index 3608eaa..5225288 100644 --- a/src/analysis/expression.cpp +++ b/src/analysis/expression.cpp @@ -126,10 +126,7 @@ void analyseModifyExpr(ModifyExprNode *node, const WalkItem &wi, WalkItem &wo) if (isNotIn(var2, wi.needCheckNullVars) && isNotIn(var2, wi.knownVars)) { - wo.removeNullVars.insert(var1); - wo.knownVars.erase(var1); - wo.knownNullVars.erase(var1); - wo.knownNonNullVars.erase(var1); + removeVar(wo, var1); } reportParmDeclNullPointer(node, @@ -140,10 +137,7 @@ void analyseModifyExpr(ModifyExprNode *node, const WalkItem &wi, WalkItem &wo) { if (var2.empty()) { // have var1 only (var1 = UNKNOWN) - wo.removeNullVars.insert(var1); - wo.knownVars.erase(var1); - wo.knownNullVars.erase(var1); - wo.knownNonNullVars.erase(var1); + removeVar(wo, var1); } else { // have var1 and var2 (var1 = var2) @@ -155,10 +149,7 @@ void analyseModifyExpr(ModifyExprNode *node, const WalkItem &wi, WalkItem &wo) else if (isNotIn(var2, wi.needCheckNullVars) && isNotIn(var2, wi.knownVars)) { - wo.removeNullVars.insert(var1); - wo.knownVars.erase(var1); - wo.knownNullVars.erase(var1); - wo.knownNonNullVars.erase(var1); + removeVar(wo, var1); } } } |