summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2015-06-19 00:31:20 +0300
committerAndrei Karas <akaras@inbox.ru>2015-06-19 00:31:20 +0300
commit4bc731cce8c5d87e18e27b4119b12d844fa5f3ec (patch)
tree278c06c97efb1dd3ba8d92d112606e764b2976a8
parent154855dc8d8ce6edf5ecd1bef8f0c9ce2b556e69 (diff)
downloadparanucker-4bc731cce8c5d87e18e27b4119b12d844fa5f3ec.tar.gz
paranucker-4bc731cce8c5d87e18e27b4119b12d844fa5f3ec.tar.bz2
paranucker-4bc731cce8c5d87e18e27b4119b12d844fa5f3ec.tar.xz
paranucker-4bc731cce8c5d87e18e27b4119b12d844fa5f3ec.zip
Switch analysis IF_STMT to new way. Add special expression flags for future usage.
-rw-r--r--src/analysis/expression.cpp32
-rw-r--r--src/analysis/statement.cpp145
-rw-r--r--src/analysis/walkitem.h7
-rw-r--r--src/logger.cpp2
4 files changed, 69 insertions, 117 deletions
diff --git a/src/analysis/expression.cpp b/src/analysis/expression.cpp
index c81378f..69047aa 100644
--- a/src/analysis/expression.cpp
+++ b/src/analysis/expression.cpp
@@ -87,7 +87,7 @@ void analyseNeExpr(NeExprNode *node, const WalkItem &wi, WalkItem &wo)
if (node->args.size() < 2 || command == FindArgs)
return;
- Log::log("analyseNeExpr 1\n");
+// Log::log("analyseNeExpr 1\n");
// PARM_DECL?
Node *node1 = skipNop(node->args[0]);
// INTEGER_CST?
@@ -101,13 +101,15 @@ void analyseNeExpr(NeExprNode *node, const WalkItem &wi, WalkItem &wo)
wi.checkNullVars.find(node1->label) != wi.checkNullVars.end() &&
node2->label == "0")
{
- Log::log("analyseNeExpr 2\n");
+// Log::log("analyseNeExpr 2\n");
wo.checkedNonNullVars.insert(node1->label);
wo.cleanExpr = true;
+ wo.uselessExpr = false;
}
else
{
wo.cleanExpr = false;
+ wo.uselessExpr = true;
}
}
@@ -117,7 +119,7 @@ void analyseEqExpr(EqExprNode *node, const WalkItem &wi, WalkItem &wo)
if (node->args.size() < 2 || command == FindArgs)
return;
- Log::log("analyseEqExpr 1\n");
+// Log::log("analyseEqExpr 1\n");
// PARM_DECL?
Node *node1 = skipNop(node->args[0]);
// INTEGER_CST?
@@ -130,13 +132,15 @@ void analyseEqExpr(EqExprNode *node, const WalkItem &wi, WalkItem &wo)
wi.checkNullVars.find(node1->label) != wi.checkNullVars.end() &&
node2->label == "0")
{
- Log::log("analyseEqExpr 2\n");
+// Log::log("analyseEqExpr 2\n");
wo.checkedNullVars.insert(node1->label);
wo.cleanExpr = true;
+ wo.uselessExpr = false;
}
else
{
wo.cleanExpr = false;
+ wo.uselessExpr = true;
}
}
@@ -146,19 +150,20 @@ void analyseTruthOrIfExpr(TruthOrIfExprNode *node, const WalkItem &wi, WalkItem
if (node->args.size() < 2 || command == FindArgs)
return;
- Log::dumpWI(node, "wo ", wo);
+// Log::dumpWI(node, "wo ", wo);
WalkItem wo1 = wo;
WalkItem wo2 = wo;
walkTree(node->args[0], wi, wo1);
walkTree(node->args[1], wi, wo2);
- Log::dumpWI(node, "wo1 ", wo1);
- Log::dumpWI(node, "wo2 ", wo2);
+// Log::dumpWI(node, "wo1 ", wo1);
+// Log::dumpWI(node, "wo2 ", wo2);
if (wo1.cleanExpr)
mergeChecked(wo, wo1);
if (wo2.cleanExpr)
mergeChecked(wo, wo2);
- wo.cleanExpr = true;
+ wo.cleanExpr = false;
wo.stopWalking = true;
+ wo.uselessExpr = wo1.uselessExpr || wo2.uselessExpr;
}
void analyseTruthAndIfExpr(TruthAndIfExprNode *node, const WalkItem &wi, WalkItem &wo)
@@ -167,22 +172,23 @@ void analyseTruthAndIfExpr(TruthAndIfExprNode *node, const WalkItem &wi, WalkIte
if (node->args.size() < 2 || command == FindArgs)
return;
- Log::dumpWI(node, "wo ", wo);
+// Log::dumpWI(node, "wo ", wo);
WalkItem wo1 = wo;
walkTree(node->args[0], wi, wo1);
WalkItem wo2 = wo1;
walkTree(node->args[1], wo1, wo2);
- Log::dumpWI(node, "wo1 ", wo1);
- Log::dumpWI(node, "wo2 ", wo2);
+// Log::dumpWI(node, "wo1 ", wo1);
+// Log::dumpWI(node, "wo2 ", wo2);
wo.stopWalking = true;
- if (wo1.cleanExpr && wo2.cleanExpr)
+ if (!wo1.uselessExpr && !wo2.uselessExpr)
{ // need combine wo1 and wo2
// for now empty simple merge, but must be compilated!
mergeChecked(wo, wo1);
mergeChecked(wo, wo2);
}
- wo.cleanExpr = true;
+ wo.cleanExpr = false;
+ wo.uselessExpr = wo1.uselessExpr || wo2.uselessExpr;
}
}
diff --git a/src/analysis/statement.cpp b/src/analysis/statement.cpp
index 24f1080..d050a62 100644
--- a/src/analysis/statement.cpp
+++ b/src/analysis/statement.cpp
@@ -49,119 +49,60 @@ void analyseIfStmt(IfStmtNode *node, const WalkItem &wi, WalkItem &wo)
Node *condNode = skipNop(node->condition);
- // for now for debug
WalkItem wci = wi;
WalkItem wco = wo;
walkTree(condNode, wci, wco);
- Log::dumpWI(node, "wco ", wco);
- // for now for debug
-
-
- if (condNode->nodeType == EQ_EXPR)
- { // if (... == ..)
- EqExprNode *eq = static_cast<EqExprNode*>(condNode);
- // need atleast two operands for EQ_EXPR node
- if (eq->args.size() < 2)
- return;
-
- // PARM_DECL?
- Node *node1 = skipNop(eq->args[0]);
- // INTEGER_CST?
- Node *node2 = skipNop(eq->args[1]);
- // if (var == 0)
- if (node1 &&
- node2 &&
- node1->nodeType == PARM_DECL &&
- node2->nodeType == INTEGER_CST &&
- wi.checkNullVars.find(node1->label) != wi.checkNullVars.end() &&
- node2->label == "0")
+// Log::dumpWI(node, "wco ", wco);
+
+ WalkItem wi2 = wi;
+ FOR_EACH (std::set<std::string>::const_iterator,
+ it,
+ wco.checkedNonNullVars)
+ {
+ wi2.checkNullVars.erase(*it);
+ }
+ walkTree(node->thenNode, wi2, wo);
+
+ wo.removeNullVars.clear();
+ const bool returned = wo.isReturned;
+ wo.isReturned = false;
+
+ wi2 = wi;
+ FOR_EACH (std::set<std::string>::const_iterator,
+ it,
+ wco.checkedNullVars)
+ {
+ wi2.checkNullVars.erase(*it);
+ }
+ walkTree(node->elseNode, wi2, wo);
+
+ wo.removeNullVars.clear();
+
+ if (returned)
+ {
+ // add variable for ignore for all parent nodes except special like IF_STMT
+ FOR_EACH (std::set<std::string>::const_iterator,
+ it,
+ wco.checkedNullVars)
{
- WalkItem wi2 = wi;
- // found check for parameter and 0.
- // walking to then branch
- walkTree(node->thenNode, wi2, wo);
- wo.removeNullVars.clear();
- const bool returned = wo.isReturned;
-// if (wo.isReturned)
-// Log::log("wo.isReturned 1\n");
-
- // From else branch remove variable what we just found.
- wi2 = wi;
- wi2.checkNullVars.erase(node1->label);
- walkTree(node->elseNode, wi2, wo);
- wo.removeNullVars.clear();
- wo.stopWalking = true;
-// if (wo.isReturned)
-// Log::log("wo.isReturned 2\n");
- wo.isReturned = false;
-
- if (returned)
- {
- //Log::log("add removeNullVars: %s\n", node1->label.c_str());
- // add variable for ignore for all parent nodes except special like IF_STMT
- wo.removeNullVars.insert(node1->label);
- wo.checkNullVars.erase(node1->label);
- }
-
- return;
+ wo.removeNullVars.insert(*it);
+ wo.checkNullVars.erase(*it);
}
}
- else if (condNode->nodeType == NE_EXPR)
- { // if (... != ..)
- NeExprNode *ne = static_cast<NeExprNode*>(condNode);
- // need atleast two operands for NE_EXPR node
- if (ne->args.size() < 2)
- return;
-
- // PARM_DECL?
- Node *node1 = skipNop(ne->args[0]);
- // INTEGER_CST?
- Node *node2 = skipNop(ne->args[1]);
- // if (var != 0)
- if (node1 &&
- node2 &&
- node1->nodeType == PARM_DECL &&
- node2->nodeType == INTEGER_CST &&
- wi.checkNullVars.find(node1->label) != wi.checkNullVars.end() &&
- node2->label == "0")
+ if (wo.isReturned)
+ {
+ // add variable for ignore for all parent nodes except special like IF_STMT
+ FOR_EACH (std::set<std::string>::const_iterator,
+ it,
+ wco.checkedNonNullVars)
{
- // found check for parameter and 0.
- // walking to then branch
- WalkItem wi2 = wi;
- wi2.checkNullVars.erase(node1->label);
- // From then branch remove variable what we just found.
- walkTree(node->thenNode, wi2, wo);
-// if (wo.isReturned)
-// Log::log("wo.isReturned 3\n");
- wo.removeNullVars.clear();
- wi2 = wi;
- // walking else node with all variables
- walkTree(node->elseNode, wi2, wo);
-// if (wo.isReturned)
-// Log::log("wo.isReturned 4\n");
- wo.removeNullVars.clear();
- wo.stopWalking = true;
-
- if (wo.isReturned && node->elseNode)
- {
- //Log::log("add removeNullVars: %s\n", node1->label.c_str());
- // add variable for ignore for all parent nodes except special like IF_STMT
- wo.removeNullVars.insert(node1->label);
- wo.checkNullVars.erase(node1->label);
- }
- wo.isReturned = false;
- return;
+ wo.removeNullVars.insert(*it);
+ wo.checkNullVars.erase(*it);
}
}
- // default case
- walkTree(node->thenNode, wi, wo);
- walkTree(node->elseNode, wi, wo);
- wo.removeNullVars.clear();
-// if (wo.isReturned)
-// Log::log("wo.isReturned 5\n");
- wo.isReturned = false;
wo.stopWalking = true;
+ wo.isReturned = false;
}
}
diff --git a/src/analysis/walkitem.h b/src/analysis/walkitem.h
index fc33049..585d196 100644
--- a/src/analysis/walkitem.h
+++ b/src/analysis/walkitem.h
@@ -32,7 +32,8 @@ struct WalkItem
checkedNonNullVars(),
stopWalking(false),
isReturned(false),
- cleanExpr(false)
+ cleanExpr(false),
+ uselessExpr(true)
{
}
@@ -43,7 +44,8 @@ struct WalkItem
checkedNonNullVars(item.checkedNonNullVars),
stopWalking(item.stopWalking),
isReturned(item.isReturned),
- cleanExpr(item.cleanExpr)
+ cleanExpr(item.cleanExpr),
+ uselessExpr(item.uselessExpr)
{
}
@@ -54,6 +56,7 @@ struct WalkItem
bool stopWalking; // stop walking on tree after this node
bool isReturned; // set if return present in child nodes
bool cleanExpr; // set if expression is only variable check without compound conditions
+ bool uselessExpr; // set if some part of expression is unknown and not checking parameters
};
diff --git a/src/logger.cpp b/src/logger.cpp
index 23cb32d..6e78829 100644
--- a/src/logger.cpp
+++ b/src/logger.cpp
@@ -202,6 +202,8 @@ void dumpWI(Node *const node,
node->label.c_str());
if (wi.cleanExpr)
Log::log(" clean");
+ if (wi.uselessExpr)
+ Log::log(" useless");
Log::log(" checkedNullVars:");
FOR_EACH (std::set<std::string>::const_iterator,
it,