summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/analysis/collections.cpp115
-rw-r--r--src/analysis/collections.h2
-rw-r--r--src/analysis/expression.cpp15
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);
}
}
}