diff options
author | Andrei Karas <akaras@inbox.ru> | 2015-07-19 01:05:26 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2015-07-19 01:05:26 +0300 |
commit | 63c96de147bcdd5dd2edc7acee872f768eca916c (patch) | |
tree | 774617e41ecd641032429fee7360a6a9e24f3d45 /src | |
parent | 04c30021f7097fd3d2aafdbe159d39510ba22e49 (diff) | |
download | paranucker-63c96de147bcdd5dd2edc7acee872f768eca916c.tar.gz paranucker-63c96de147bcdd5dd2edc7acee872f768eca916c.tar.bz2 paranucker-63c96de147bcdd5dd2edc7acee872f768eca916c.tar.xz paranucker-63c96de147bcdd5dd2edc7acee872f768eca916c.zip |
Add ability for detect what variable will be non null after if block.
Example:
if (!ptr)
{
ptr1 = new data;
}
// here ptr1 always non null
Diffstat (limited to 'src')
-rw-r--r-- | src/analysis/collections.cpp | 31 | ||||
-rw-r--r-- | src/analysis/collections.h | 6 | ||||
-rw-r--r-- | src/analysis/statement.cpp | 4 |
3 files changed, 41 insertions, 0 deletions
diff --git a/src/analysis/collections.cpp b/src/analysis/collections.cpp index 4fb861d..d8d9510 100644 --- a/src/analysis/collections.cpp +++ b/src/analysis/collections.cpp @@ -58,6 +58,20 @@ void addNeedCheckNullVars2(WalkItem &wi, WalkItem &wo) } } +void removeNeedCheckNullVars2(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.checkedThenNullVars) && + isIn(it, wco.checkedElseNonNullVars)) + { + removeNeedCheckNullVarOnly(wo, it); + addNonNullVar(wo, it); + } + } +} + // remove one variable from null pointer checks void removeNeedCheckNullVar(WalkItem &wi, std::string str) { @@ -379,6 +393,23 @@ void addKnownNonNullVarsWithLinked(WalkItem &wo, WalkItem &wi, std::set<std::str } } +void addKnownNonNullVarWithLinked(WalkItem &wo, WalkItem &wi, const std::string &var) +{ + wo.knownNonNullVars.insert(var); + auto it2 = wi.linkedVars.find(var); + if (it2 == wi.linkedVars.end() && + isIn(var, wi.linkedReverseVars)) + { + wo.knownNonNullVars.insert(wi.linkedReverseVars[var]); + it2 = wi.linkedVars.find(wi.linkedReverseVars[var]); + } + if (it2 != wi.linkedVars.end()) + { + const StringSet &linked = (*it2).second; + wo.knownNonNullVars.insert(linked.begin(), linked.end()); + } +} + void removeVar(WalkItem &wi, const std::string &var) { wi.removeNullVars.insert(var); diff --git a/src/analysis/collections.h b/src/analysis/collections.h index a03cbe5..1e36bf0 100644 --- a/src/analysis/collections.h +++ b/src/analysis/collections.h @@ -86,6 +86,12 @@ namespace Analysis void enforceNeedCheckNullVars(WalkItem &wi); void removeLinkVarOnly(WalkItem &wi, const std::string &var); + + void removeNeedCheckNullVars2(WalkItem &wco, WalkItem &wi, WalkItem &wo); + + void addKnownNonNullVarWithLinked(WalkItem &wo, WalkItem &wi, const std::string &var); + + void removeNeedCheckNullVarOnly(WalkItem &wi, const std::string &var); } #endif // ANALYSIS_COLLECTIONS_H diff --git a/src/analysis/statement.cpp b/src/analysis/statement.cpp index 5f1f95b..39c03d2 100644 --- a/src/analysis/statement.cpp +++ b/src/analysis/statement.cpp @@ -126,6 +126,7 @@ void analyseCondition(Node *node, else if (thenNode) { addNeedCheckNullVars2(wo2, wo); + removeNeedCheckNullVars2(wco, wo2, wo); } if (wo3.isReturned || wo3.isContinued) { @@ -144,6 +145,7 @@ void analyseCondition(Node *node, else if (elseNode) { addNeedCheckNullVars2(wo3, wo); + removeNeedCheckNullVars2(wco, wo2, wo); } if ((wo2.isReturned || wo2.isContinued) && (wo3.isReturned || wo3.isContinued)) { @@ -242,6 +244,8 @@ void analyseWhileStmt(WhileStmtNode *node, const WalkItem &wi, WalkItem &wo) walkTree(condNode, wci, wco); command = oldCommand; Log::dumpWI(node, "wco2 ", wco); + + removeNeedCheckNullVars2(wco, wo2, wo); } wo.isReturned = false; |