summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2015-07-20 00:17:27 +0300
committerAndrei Karas <akaras@inbox.ru>2015-07-20 00:17:27 +0300
commita673999f9e466cc8206120cf06af28f5d1e249bb (patch)
tree6cec86ca37551b3d35387c875a9d05d38a6cf52b
parent379c0323eb20cbdd3998d460e21110a3498f6cee (diff)
downloadparanucker-a673999f9e466cc8206120cf06af28f5d1e249bb.tar.gz
paranucker-a673999f9e466cc8206120cf06af28f5d1e249bb.tar.bz2
paranucker-a673999f9e466cc8206120cf06af28f5d1e249bb.tar.xz
paranucker-a673999f9e466cc8206120cf06af28f5d1e249bb.zip
Add ability for detect what variable will be non null after if block (in else branch)
-rw-r--r--src/analysis/collections.cpp16
-rw-r--r--src/analysis/collections.h4
-rw-r--r--src/analysis/statement.cpp6
3 files changed, 21 insertions, 5 deletions
diff --git a/src/analysis/collections.cpp b/src/analysis/collections.cpp
index e9acce6..12fcd7a 100644
--- a/src/analysis/collections.cpp
+++ b/src/analysis/collections.cpp
@@ -69,7 +69,7 @@ void removeKnownNullVars2(WalkItem &wi, WalkItem &wo)
}
}
-void removeNeedCheckNullVars2(WalkItem &wco, WalkItem &wi, WalkItem &wo)
+void removeNeedCheckNullVarsThen(WalkItem &wco, WalkItem &wi, WalkItem &wo)
{
FOR_EACH (it, wi.knownNonNullVars)
{
@@ -83,6 +83,20 @@ void removeNeedCheckNullVars2(WalkItem &wco, WalkItem &wi, WalkItem &wo)
}
}
+void removeNeedCheckNullVarsElse(WalkItem &wco, WalkItem &wi, WalkItem &wo)
+{
+ FOR_EACH (it, wi.knownNonNullVars)
+ {
+ // check what it presend in if condition like if (!it) and in else like if (it)
+ if (isIn(it, wco.checkedElseNullVars) &&
+ isIn(it, wco.checkedThenNonNullVars))
+ {
+ removeNeedCheckNullVarOnly(wo, it);
+ addNonNullVar(wo, it);
+ }
+ }
+}
+
// remove one variable from null pointer checks
void removeNeedCheckNullVar(WalkItem &wi, std::string str)
{
diff --git a/src/analysis/collections.h b/src/analysis/collections.h
index e81cc7e..4f6810f 100644
--- a/src/analysis/collections.h
+++ b/src/analysis/collections.h
@@ -90,7 +90,9 @@ namespace Analysis
void removeLinkVarOnly(WalkItem &wi, const std::string &var);
- void removeNeedCheckNullVars2(WalkItem &wco, WalkItem &wi, WalkItem &wo);
+ void removeNeedCheckNullVarsThen(WalkItem &wco, WalkItem &wi, WalkItem &wo);
+
+ void removeNeedCheckNullVarsElse(WalkItem &wco, WalkItem &wi, WalkItem &wo);
void addKnownNonNullVarWithLinked(WalkItem &wo, WalkItem &wi, const std::string &var);
diff --git a/src/analysis/statement.cpp b/src/analysis/statement.cpp
index 573b5ec..0f9f2eb 100644
--- a/src/analysis/statement.cpp
+++ b/src/analysis/statement.cpp
@@ -126,7 +126,7 @@ void analyseCondition(Node *node,
else if (thenNode)
{
addNeedCheckNullVars2(wo2, wo);
- removeNeedCheckNullVars2(wco, wo2, wo);
+ removeNeedCheckNullVarsThen(wco, wo2, wo);
removeKnownNullVars2(wo2, wo);
}
if (wo3.isReturned || wo3.isContinued)
@@ -146,7 +146,7 @@ void analyseCondition(Node *node,
else if (elseNode)
{
addNeedCheckNullVars2(wo3, wo);
- removeNeedCheckNullVars2(wco, wo2, wo);
+ removeNeedCheckNullVarsElse(wco, wo3, wo);
removeKnownNullVars2(wo3, wo);
}
if ((wo2.isReturned || wo2.isContinued) && (wo3.isReturned || wo3.isContinued))
@@ -249,7 +249,7 @@ void analyseWhileStmt(WhileStmtNode *node, const WalkItem &wi, WalkItem &wo)
command = oldCommand;
Log::dumpWI(node, "wco2 ", wco);
- removeNeedCheckNullVars2(wcoSaved, wo2Saved, wo);
+ removeNeedCheckNullVarsThen(wcoSaved, wo2Saved, wo);
removeKnownNullVars2(wo2Saved, wo);
}