summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2015-07-08 00:34:52 +0300
committerAndrei Karas <akaras@inbox.ru>2015-07-08 14:09:58 +0300
commit4403372a6292fcfeff4d29383e0fc964abaeb592 (patch)
treece546f534f60e5c7d1c7dd975159484ba63a415f /src
parentc493b9059f0289585c7aa7c2be71ec7fd5aa9116 (diff)
downloadparanucker-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.cpp6
-rw-r--r--src/analysis/collections.cpp30
-rw-r--r--src/analysis/collections.h5
-rw-r--r--src/analysis/statement.cpp74
-rw-r--r--src/analysis/statement.h5
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