diff options
-rw-r--r-- | src/analysis/expression.cpp | 32 | ||||
-rw-r--r-- | src/analysis/statement.cpp | 145 | ||||
-rw-r--r-- | src/analysis/walkitem.h | 7 | ||||
-rw-r--r-- | src/logger.cpp | 2 |
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, |