diff options
-rw-r--r-- | src/analysis/analysis.cpp | 4 | ||||
-rw-r--r-- | src/analysis/expression.cpp | 42 | ||||
-rw-r--r-- | src/analysis/expression.h | 3 | ||||
-rw-r--r-- | src/analysis/statement.cpp | 1 | ||||
-rw-r--r-- | src/analysis/walkitem.h | 8 | ||||
-rw-r--r-- | src/logger.cpp | 5 |
6 files changed, 56 insertions, 7 deletions
diff --git a/src/analysis/analysis.cpp b/src/analysis/analysis.cpp index caca286..0deb2df 100644 --- a/src/analysis/analysis.cpp +++ b/src/analysis/analysis.cpp @@ -39,6 +39,7 @@ #include "nodes/expr/nop_expr.h" #include "nodes/expr/pointerplus_expr.h" #include "nodes/expr/return_expr.h" +#include "nodes/expr/truthandif_expr.h" #include "nodes/expr/truthorif_expr.h" #include "nodes/ref/component_ref.h" @@ -197,6 +198,9 @@ void analyseNode(Node *node, const WalkItem &wi, WalkItem &wo) case TRUTH_ORIF_EXPR: analyseTruthOrIfExpr(static_cast<TruthOrIfExprNode*>(node), wi2, wo); break; + case TRUTH_ANDIF_EXPR: + analyseTruthAndIfExpr(static_cast<TruthAndIfExprNode*>(node), wi2, wo); + break; case RETURN_EXPR: analyseReturnExpr(static_cast<ReturnExprNode*>(node), wi2, wo); break; diff --git a/src/analysis/expression.cpp b/src/analysis/expression.cpp index 0228f4b..c81378f 100644 --- a/src/analysis/expression.cpp +++ b/src/analysis/expression.cpp @@ -31,6 +31,7 @@ #include "nodes/expr/ne_expr.h" #include "nodes/expr/pointerplus_expr.h" #include "nodes/expr/return_expr.h" +#include "nodes/expr/truthandif_expr.h" #include "nodes/expr/truthorif_expr.h" #include "nodes/ref/indirect_ref.h" @@ -102,6 +103,11 @@ void analyseNeExpr(NeExprNode *node, const WalkItem &wi, WalkItem &wo) { Log::log("analyseNeExpr 2\n"); wo.checkedNonNullVars.insert(node1->label); + wo.cleanExpr = true; + } + else + { + wo.cleanExpr = false; } } @@ -126,6 +132,11 @@ void analyseEqExpr(EqExprNode *node, const WalkItem &wi, WalkItem &wo) { Log::log("analyseEqExpr 2\n"); wo.checkedNullVars.insert(node1->label); + wo.cleanExpr = true; + } + else + { + wo.cleanExpr = false; } } @@ -142,9 +153,36 @@ void analyseTruthOrIfExpr(TruthOrIfExprNode *node, const WalkItem &wi, WalkItem walkTree(node->args[1], wi, wo2); Log::dumpWI(node, "wo1 ", wo1); Log::dumpWI(node, "wo2 ", wo2); - mergeChecked(wo, wo1); - mergeChecked(wo, wo2); + if (wo1.cleanExpr) + mergeChecked(wo, wo1); + if (wo2.cleanExpr) + mergeChecked(wo, wo2); + wo.cleanExpr = true; wo.stopWalking = true; } +void analyseTruthAndIfExpr(TruthAndIfExprNode *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; + 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); + + wo.stopWalking = true; + if (wo1.cleanExpr && wo2.cleanExpr) + { // need combine wo1 and wo2 + // for now empty simple merge, but must be compilated! + mergeChecked(wo, wo1); + mergeChecked(wo, wo2); + } + wo.cleanExpr = true; +} + } diff --git a/src/analysis/expression.h b/src/analysis/expression.h index 9d2aef8..b7851fd 100644 --- a/src/analysis/expression.h +++ b/src/analysis/expression.h @@ -28,6 +28,7 @@ struct ModifyExprNode; struct NeExprNode; struct PointerPlusExprNode; struct ReturnExprNode; +struct TruthAndIfExprNode; struct TruthOrIfExprNode; struct WalkItem; @@ -46,6 +47,8 @@ namespace Analysis void analyseEqExpr(EqExprNode *node, const WalkItem &wi, WalkItem &wo); void analyseTruthOrIfExpr(TruthOrIfExprNode *node, const WalkItem &wi, WalkItem &wo); + + void analyseTruthAndIfExpr(TruthAndIfExprNode *node, const WalkItem &wi, WalkItem &wo); } #endif // ANALYSIS_EXPRESSION_H diff --git a/src/analysis/statement.cpp b/src/analysis/statement.cpp index 4366e2c..24f1080 100644 --- a/src/analysis/statement.cpp +++ b/src/analysis/statement.cpp @@ -52,7 +52,6 @@ void analyseIfStmt(IfStmtNode *node, const WalkItem &wi, WalkItem &wo) // 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 diff --git a/src/analysis/walkitem.h b/src/analysis/walkitem.h index 11245bf..fc33049 100644 --- a/src/analysis/walkitem.h +++ b/src/analysis/walkitem.h @@ -31,7 +31,8 @@ struct WalkItem checkedNullVars(), checkedNonNullVars(), stopWalking(false), - isReturned(false) + isReturned(false), + cleanExpr(false) { } @@ -41,7 +42,8 @@ struct WalkItem checkedNullVars(item.checkedNullVars), checkedNonNullVars(item.checkedNonNullVars), stopWalking(item.stopWalking), - isReturned(item.isReturned) + isReturned(item.isReturned), + cleanExpr(item.cleanExpr) { } @@ -51,7 +53,7 @@ struct WalkItem 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 + bool cleanExpr; // set if expression is only variable check without compound conditions }; diff --git a/src/logger.cpp b/src/logger.cpp index dbe1090..23cb32d 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -196,10 +196,13 @@ void dumpWI(Node *const node, const std::string &name, WalkItem &wi) { - Log::log("%s%s %s checkedNullVars:", + Log::log("%s%s %s", name.c_str(), node->nodeTypeName.c_str(), node->label.c_str()); + if (wi.cleanExpr) + Log::log(" clean"); + Log::log(" checkedNullVars:"); FOR_EACH (std::set<std::string>::const_iterator, it, wi.checkedNullVars) |