summaryrefslogtreecommitdiff
path: root/src/analysis/collections.cpp
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2015-07-04 17:43:29 +0300
committerAndrei Karas <akaras@inbox.ru>2015-07-04 17:43:29 +0300
commit4cde22214f0f91050c8e0e3b73de0f006fd6f3f6 (patch)
treec6b519de03cb3acf83ae2cb25e3f38ab3a4f0e5c /src/analysis/collections.cpp
parent3f3568923589b2c5d8c269e623e7a8a3751011f1 (diff)
downloadparanucker-4cde22214f0f91050c8e0e3b73de0f006fd6f3f6.tar.gz
paranucker-4cde22214f0f91050c8e0e3b73de0f006fd6f3f6.tar.bz2
paranucker-4cde22214f0f91050c8e0e3b73de0f006fd6f3f6.tar.xz
paranucker-4cde22214f0f91050c8e0e3b73de0f006fd6f3f6.zip
Fix most issues with linked vars.
Diffstat (limited to 'src/analysis/collections.cpp')
-rw-r--r--src/analysis/collections.cpp115
1 files changed, 94 insertions, 21 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);
+}
+
}