diff options
author | Andrei Karas <akaras@inbox.ru> | 2015-07-08 00:34:52 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2015-07-08 14:09:58 +0300 |
commit | 4403372a6292fcfeff4d29383e0fc964abaeb592 (patch) | |
tree | ce546f534f60e5c7d1c7dd975159484ba63a415f /src | |
parent | c493b9059f0289585c7aa7c2be71ec7fd5aa9116 (diff) | |
download | paranucker-4403372a6292fcfeff4d29383e0fc964abaeb592.tar.gz paranucker-4403372a6292fcfeff4d29383e0fc964abaeb592.tar.bz2 paranucker-4403372a6292fcfeff4d29383e0fc964abaeb592.tar.xz paranucker-4403372a6292fcfeff4d29383e0fc964abaeb592.zip |
Add WHILE_STMT node analysis.
This add basic support for while(exprt) {code}
Diffstat (limited to 'src')
-rw-r--r-- | src/analysis/analysis.cpp | 6 | ||||
-rw-r--r-- | src/analysis/collections.cpp | 30 | ||||
-rw-r--r-- | src/analysis/collections.h | 5 | ||||
-rw-r--r-- | src/analysis/statement.cpp | 74 | ||||
-rw-r--r-- | src/analysis/statement.h | 5 |
5 files changed, 119 insertions, 1 deletions
diff --git a/src/analysis/analysis.cpp b/src/analysis/analysis.cpp index de4fec3..70905e6 100644 --- a/src/analysis/analysis.cpp +++ b/src/analysis/analysis.cpp @@ -56,6 +56,7 @@ #include "nodes/ref/component_ref.h" #include "nodes/stmt/if_stmt.h" +#include "nodes/stmt/while_stmt.h" #include "localconsts.h" @@ -198,7 +199,7 @@ void analyseNode(Node *node, const WalkItem &wi, WalkItem &wo) // remove check for vars what was requested from some childs. // Except IF_STMT. Removing handled inside analyse function. - if (node != IF_STMT) + if (node != IF_STMT && node != WHILE_STMT) { removeNeedCheckNullVarsSetAll(wi2, wi2.removeNullVarsAll); } @@ -276,6 +277,9 @@ void analyseNode(Node *node, const WalkItem &wi, WalkItem &wo) case IF_STMT: analyseIfStmt(static_cast<IfStmtNode*>(node), wi2, wo); break; + case WHILE_STMT: + analyseWhileStmt(static_cast<WhileStmtNode*>(node), wi2, wo); + break; case COMPONENT_REF: analyseComponentRef(static_cast<ComponentRefNode*>(node), wi2, wo); break; diff --git a/src/analysis/collections.cpp b/src/analysis/collections.cpp index a475acc..0f3a8f8 100644 --- a/src/analysis/collections.cpp +++ b/src/analysis/collections.cpp @@ -35,6 +35,28 @@ void addNeedCheckNullVars(WalkItem &wi, WalkItem &wo) { wo.needCheckNullVars.insert(it); wo.knownVars.insert(it); +/* + wo.knownNonNullVars.erase(it); + wo.knownNullVars.erase(it); + wo.removeNullVars.erase(it); + wo.removeNullVarsAll.erase(it); + wo.addNullVars.insert(it); +*/ + } +} + +// add variables null pointer checks +void addNeedCheckNullVars2(WalkItem &wi, WalkItem &wo) +{ + FOR_EACH (it, wi.addNullVars) + { + wo.needCheckNullVars.insert(it); + wo.knownVars.insert(it); + wo.knownNonNullVars.erase(it); + wo.knownNullVars.erase(it); + wo.removeNullVars.erase(it); + wo.removeNullVarsAll.erase(it); + wo.addNullVars.insert(it); } } @@ -362,4 +384,12 @@ void removeVar(WalkItem &wi, const std::string &var) removeNeedCheckNullVarOnly(wi, var); } +void enforceNeedCheckNullVars(WalkItem &wi) +{ + FOR_EACH (it, wi.needCheckNullVars) + { + wi.removeNullVars.erase(it); + } +} + } diff --git a/src/analysis/collections.h b/src/analysis/collections.h index 388a50f..8a50376 100644 --- a/src/analysis/collections.h +++ b/src/analysis/collections.h @@ -33,6 +33,9 @@ namespace Analysis void addNeedCheckNullVars(WalkItem &wi, WalkItem &wo); + void addNeedCheckNullVars2(WalkItem &wi, + WalkItem &wo); + void addUnknownVar(WalkItem &wi, const std::string &var); @@ -79,6 +82,8 @@ namespace Analysis std::set<std::string> &vars); void removeVar(WalkItem &wi, const std::string &var); + + void enforceNeedCheckNullVars(WalkItem &wi); } #endif // ANALYSIS_COLLECTIONS_H diff --git a/src/analysis/statement.cpp b/src/analysis/statement.cpp index 32b22f3..dd370fa 100644 --- a/src/analysis/statement.cpp +++ b/src/analysis/statement.cpp @@ -35,6 +35,7 @@ #include "nodes/ref/indirect_ref.h" #include "nodes/stmt/if_stmt.h" +#include "nodes/stmt/while_stmt.h" #include <set> @@ -121,6 +122,10 @@ void analyseCondition(Node *node, addKnownNullVarsWithLinked(wo, wco, wco.checkedElseNullVars); } } + else + { +// addNeedCheckNullVars2(wo2, wo); + } if (wo3.isReturned) { // add variable for ignore for all parent nodes except special like IF_STMT @@ -135,6 +140,10 @@ void analyseCondition(Node *node, addKnownNullVarsWithLinked(wo, wco, wco.checkedThenNullVars); } } + else + { +// addNeedCheckNullVars2(wo3, wo); + } if (wo2.isReturned && wo3.isReturned) { // add variable for ignore for all parent nodes except special like IF_STMT @@ -166,4 +175,69 @@ void analyseIfStmt(IfStmtNode *node, const WalkItem &wi, WalkItem &wo) wo); } +void analyseWhileStmt(WhileStmtNode *node, const WalkItem &wi, WalkItem &wo) +{ + // need condition node + if (!node->condition || checkCommand(FindArgs)) + return; + + Node *condNode = skipNop(node->condition); + Node *bodyNode = skipNop(node->body); + if (!condNode) + return; + + WalkItem wci = wi; + WalkItem wco = wo; + WalkItem wo2 = wo; + + walkTree(condNode, wci, wco); + Log::dumpWI(node, "wco ", wco); + + WalkItem wi2 = wi; + if (wco.cleanExpr) + removeNeedCheckNullVarsSetAll(wi2, wco.checkedThenNonNullVars); +// wi2.needCheckNullVars.insert(wco.checkedThenNullVars.begin(), +// wco.checkedThenNullVars.end()); + addKnownNullVarsWithLinked(wi2, wco, wco.checkedThenNullVars); + addKnownNonNullVarsWithLinked(wi2, wco, wco.checkedThenNonNullVars); + wi2.needCheckNullVars = wi2.knownVars; + enforceNeedCheckNullVars(wi2); + removeNeedCheckNullVarsSetAll(wi2, wi2.knownNonNullVars); + wo2 = wi2; + Log::dumpWI(node, "wi2 body ", wi2); + + reportParmDeclNullPointer(node, + bodyNode, + wi2); + walkTree(bodyNode, wi2, wo2); + Log::dumpWI(node, "wo2 body ", wo2); + + if (wo2.cleanExpr) + mergeElseNullChecked(wo, wo2); + + if (wo2.isReturned) + { + // add variable for ignore for all parent nodes except special like IF_STMT + FOR_EACH (it, wco.checkedElseNonNullVars) + { + wo.removeNullVarsAll.insert(it); + removeNeedCheckNullVar(wo, it); + } + addKnownNonNullVarsWithLinked(wo, wco, wco.checkedElseNonNullVars); + if (wco.cleanExpr) + { + addKnownNullVarsWithLinked(wo, wco, wco.checkedElseNullVars); + } + } + else + { +// addNeedCheckNullVars2(wo2, wo); + } + + wo.isReturned = false; + wo.cleanExpr = true; + wo.stopWalking = true; + wo.uselessExpr = false; +} + } diff --git a/src/analysis/statement.h b/src/analysis/statement.h index 08c6869..ab15a7a 100644 --- a/src/analysis/statement.h +++ b/src/analysis/statement.h @@ -25,6 +25,7 @@ struct IfStmtNode; struct Node; struct WalkItem; +struct WhileStmtNode; namespace Analysis { @@ -38,6 +39,10 @@ namespace Analysis void analyseIfStmt(IfStmtNode *node, const WalkItem &wi, WalkItem &wo); + + void analyseWhileStmt(WhileStmtNode *node, + const WalkItem &wi, + WalkItem &wo); } #endif // ANALYSIS_STATEMENT_H |