diff options
author | Andrei Karas <akaras@inbox.ru> | 2015-06-18 17:28:59 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2015-06-18 17:28:59 +0300 |
commit | 4125da9e48ff0f6240ad705d8a47323b70ee59c1 (patch) | |
tree | 5d5b630f13419296fb8ca94167b78a33ef842c5b | |
parent | d2b4c53238a9c455eb15d58526b7e5f43100f457 (diff) | |
download | paranucker-4125da9e48ff0f6240ad705d8a47323b70ee59c1.tar.gz paranucker-4125da9e48ff0f6240ad705d8a47323b70ee59c1.tar.bz2 paranucker-4125da9e48ff0f6240ad705d8a47323b70ee59c1.tar.xz paranucker-4125da9e48ff0f6240ad705d8a47323b70ee59c1.zip |
Improve analysis for nodes EQ_EXPR, NE_EXPR, TRUTH_ORIF_EXPR (incomplete).
-rw-r--r-- | src/analysis/analysis.cpp | 8 | ||||
-rw-r--r-- | src/analysis/analysis.h | 2 | ||||
-rw-r--r-- | src/analysis/expression.cpp | 29 | ||||
-rw-r--r-- | src/analysis/statement.cpp | 10 | ||||
-rw-r--r-- | src/analysis/walkitem.h | 13 | ||||
-rw-r--r-- | src/logger.cpp | 28 | ||||
-rw-r--r-- | src/logger.h | 9 |
7 files changed, 87 insertions, 12 deletions
diff --git a/src/analysis/analysis.cpp b/src/analysis/analysis.cpp index ecdb079..caca286 100644 --- a/src/analysis/analysis.cpp +++ b/src/analysis/analysis.cpp @@ -141,6 +141,14 @@ Node *skipNop(Node *node) return node; } +void mergeChecked(WalkItem &wi1, WalkItem &wi2) +{ + wi1.checkedNullVars.insert(wi2.checkedNullVars.begin(), + wi2.checkedNullVars.end()); + wi1.checkedNonNullVars.insert(wi2.checkedNonNullVars.begin(), + wi2.checkedNonNullVars.end()); +} + void analyseNode(Node *node, const WalkItem &wi, WalkItem &wo) { if (!node) diff --git a/src/analysis/analysis.h b/src/analysis/analysis.h index df954b2..7215850 100644 --- a/src/analysis/analysis.h +++ b/src/analysis/analysis.h @@ -42,6 +42,8 @@ namespace Analysis void removeCheckNullVars(WalkItem &wi); Node *skipNop(Node *node); + + void mergeChecked(WalkItem &wi1, WalkItem &wi2); } #endif // ANALYSIS_ANALYSIS_H diff --git a/src/analysis/expression.cpp b/src/analysis/expression.cpp index c057f88..0228f4b 100644 --- a/src/analysis/expression.cpp +++ b/src/analysis/expression.cpp @@ -83,9 +83,10 @@ void analyseReturnExpr(ReturnExprNode *node, const WalkItem &wi, WalkItem &wo) void analyseNeExpr(NeExprNode *node, const WalkItem &wi, WalkItem &wo) { // need two args for check - if (node->args.size() < 2 || !wi.isExpr || command == FindArgs) + if (node->args.size() < 2 || command == FindArgs) return; + Log::log("analyseNeExpr 1\n"); // PARM_DECL? Node *node1 = skipNop(node->args[0]); // INTEGER_CST? @@ -99,18 +100,18 @@ void analyseNeExpr(NeExprNode *node, const WalkItem &wi, WalkItem &wo) wi.checkNullVars.find(node1->label) != wi.checkNullVars.end() && node2->label == "0") { - wo.removeNullVars.insert(node1->label); - wo.checkNullVars.erase(node1->label); + Log::log("analyseNeExpr 2\n"); + wo.checkedNonNullVars.insert(node1->label); } } void analyseEqExpr(EqExprNode *node, const WalkItem &wi, WalkItem &wo) { // need two args for check - if (node->args.size() < 2 || !wi.isExpr || command == FindArgs) + if (node->args.size() < 2 || command == FindArgs) return; -/* + Log::log("analyseEqExpr 1\n"); // PARM_DECL? Node *node1 = skipNop(node->args[0]); // INTEGER_CST? @@ -123,13 +124,27 @@ 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"); + wo.checkedNullVars.insert(node1->label); } -*/ -// do nothing for now } void analyseTruthOrIfExpr(TruthOrIfExprNode *node, const WalkItem &wi, WalkItem &wo) { + // need two args for check + if (node->args.size() < 2 || command == FindArgs) + return; + + 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); + mergeChecked(wo, wo1); + mergeChecked(wo, wo2); + wo.stopWalking = true; } } diff --git a/src/analysis/statement.cpp b/src/analysis/statement.cpp index 394dcfe..4366e2c 100644 --- a/src/analysis/statement.cpp +++ b/src/analysis/statement.cpp @@ -48,6 +48,16 @@ void analyseIfStmt(IfStmtNode *node, const WalkItem &wi, WalkItem &wo) return; Node *condNode = skipNop(node->condition); + + // for now for debug + WalkItem wci = wi; + WalkItem wco = wo; + wci.isExpr = true; + 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); diff --git a/src/analysis/walkitem.h b/src/analysis/walkitem.h index 29352c0..11245bf 100644 --- a/src/analysis/walkitem.h +++ b/src/analysis/walkitem.h @@ -28,22 +28,27 @@ struct WalkItem WalkItem() : checkNullVars(), removeNullVars(), + checkedNullVars(), + checkedNonNullVars(), stopWalking(false), - isReturned(false), - isExpr(false) + isReturned(false) { } WalkItem(const WalkItem &item) : checkNullVars(item.checkNullVars), removeNullVars(item.removeNullVars), + checkedNullVars(item.checkedNullVars), + checkedNonNullVars(item.checkedNonNullVars), stopWalking(item.stopWalking), isReturned(item.isReturned) { } - std::set<std::string> checkNullVars; - std::set<std::string> removeNullVars; + std::set<std::string> checkNullVars; // need check for usage without null pointer check + std::set<std::string> removeNullVars; // need remove vars from parent checkNullVars + std::set<std::string> checkedNullVars; // vars checked for null in expressions + std::set<std::string> checkedNonNullVars; // vars checked for nonnull in expressions bool stopWalking; // stop walking on tree after this node bool isReturned; // set if return present in child nodes bool isExpr; // set if walking on expression for if other kind nodes diff --git a/src/logger.cpp b/src/logger.cpp index 1203c78..dbe1090 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -22,8 +22,12 @@ #include "command.h" #include "includes.h" +#include "analysis/walkitem.h" + #include "nodes/base/node.h" +#include <set> + #include "localconsts.h" namespace Log @@ -188,6 +192,30 @@ void dumpAttr(const Node *const node, int num, bool isReturned) fprintf(stderr, " walkTree%d: %d\n", num, isReturned ? 1 : 0); } +void dumpWI(Node *const node, + const std::string &name, + WalkItem &wi) +{ + Log::log("%s%s %s checkedNullVars:", + name.c_str(), + node->nodeTypeName.c_str(), + node->label.c_str()); + FOR_EACH (std::set<std::string>::const_iterator, + it, + wi.checkedNullVars) + { + Log::log("%s, ", (*it).c_str()); + } + Log::log(" checkedNonNullVars:"); + FOR_EACH (std::set<std::string>::const_iterator, + it, + wi.checkedNonNullVars) + { + Log::log("%s, ", (*it).c_str()); + } + Log::log("\n"); +} + void warn(const int loc, const std::string &message, const std::string ¶m) diff --git a/src/logger.h b/src/logger.h index 8fca641..6e7e982 100644 --- a/src/logger.h +++ b/src/logger.h @@ -23,6 +23,7 @@ #include <string> struct Node; +struct WalkItem; namespace Log { @@ -55,7 +56,13 @@ namespace Log const std::string &message, const std::string ¶m); - void dumpAttr(const Node *const node, int num, bool isReturned); + void dumpAttr(const Node *const node, + int num, + bool isReturned); + + void dumpWI(Node *const node, + const std::string &name, + WalkItem &wi); } #endif // LOGGER_H |