From e8e75ca7639bf3a8e34391aaa33f90c18905e977 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Thu, 11 Jun 2015 23:42:07 +0300 Subject: Fix some issues in test6. Now if variable check happend before other code variable will not trigger warning. Example: if (!a) return; *a = 10; --- src/analysis/analysis.cpp | 40 ++++++++++++++++++++++++++-------------- src/analysis/analysis.h | 2 ++ src/analysis/statement.cpp | 26 +++++++++++++++++++------- 3 files changed, 47 insertions(+), 21 deletions(-) diff --git a/src/analysis/analysis.cpp b/src/analysis/analysis.cpp index 011fbf1..86fd683 100644 --- a/src/analysis/analysis.cpp +++ b/src/analysis/analysis.cpp @@ -42,6 +42,19 @@ namespace Analysis { +// remove check null vars. +void removeCheckNullVars(WalkItem &wi) +{ + FOR_EACH (std::set::const_iterator, it, wi.removeNullVars) + { + // found var for deletion + if (wi.checkNullVars.find(*it) != wi.checkNullVars.end()) + { + wi.checkNullVars.erase(*it); + } + } +} + void startWalkTree(Node *node) { WalkItem wi; @@ -55,15 +68,8 @@ void walkTree(Node *node, const WalkItem &wi, WalkItem &wo) return; WalkItem wi2 = wi; - FOR_EACH (std::set::const_iterator, it, wi2.removeNullVars) - { - // found var for deletion - if (wi2.checkNullVars.find(*it) != wi2.checkNullVars.end()) - { - wi2.checkNullVars.erase(*it); - } - } analyseNode(node, wi2, wo); + removeCheckNullVars(wi2); if (wo.stopWalking) { @@ -111,28 +117,34 @@ void analyseNode(Node *node, const WalkItem &wi, WalkItem &wo) Log::log("\n"); } + WalkItem wi2 = wi; wo = wi; + // remove check for vars what was requested from some childs. + // Except IF_STMT. Removing handled inside analyse function. + if (node->nodeType != IF_STMT) + removeCheckNullVars(wi2); + // searching function declaration switch (node->nodeType) { case FUNCTION_DECL: - analyseFunction(static_cast(node), wi, wo); + analyseFunction(static_cast(node), wi2, wo); break; case ADDR_EXPR: - analyseAddrExpr(static_cast(node), wi, wo); + analyseAddrExpr(static_cast(node), wi2, wo); break; case MODIFY_EXPR: - analyseModifyExpr(static_cast(node), wi, wo); + analyseModifyExpr(static_cast(node), wi2, wo); break; case POINTER_PLUS_EXPR: - analysePointerPlusExpr(static_cast(node), wi, wo); + analysePointerPlusExpr(static_cast(node), wi2, wo); break; case VAR_DECL: - analyseVarDecl(static_cast(node), wi, wo); + analyseVarDecl(static_cast(node), wi2, wo); break; case IF_STMT: - analyseIfStmt(static_cast(node), wi, wo); + analyseIfStmt(static_cast(node), wi2, wo); break; default: break; diff --git a/src/analysis/analysis.h b/src/analysis/analysis.h index bfc3327..596988c 100644 --- a/src/analysis/analysis.h +++ b/src/analysis/analysis.h @@ -34,6 +34,8 @@ namespace Analysis void analyseNode(Node *node, const WalkItem &wi, WalkItem &wo); int findBackLocation(Node *node); + + void removeCheckNullVars(WalkItem &wi); } #endif // ANALYSIS_ANALYSIS_H diff --git a/src/analysis/statement.cpp b/src/analysis/statement.cpp index a585adb..4d948d3 100644 --- a/src/analysis/statement.cpp +++ b/src/analysis/statement.cpp @@ -57,7 +57,7 @@ void analyseIfStmt(IfStmtNode *node, const WalkItem &wi, WalkItem &wo) Node *node1 = eq->args[0]; // INTEGER_CST? Node *node2 = eq->args[1]; - // if (var == const) + // if (var == 0) if (node1->nodeType == PARM_DECL && node2->nodeType == INTEGER_CST && wi.checkNullVars.find(node1->label) != wi.checkNullVars.end() && @@ -67,10 +67,13 @@ void analyseIfStmt(IfStmtNode *node, const WalkItem &wi, WalkItem &wo) // found check for parameter and 0. // walking to then branch walkTree(node->thenNode, wi2, wo); + wo.removeNullVars.clear(); + // 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; //Log::log("add removeNullVars: %s\n", node1->label.c_str()); @@ -79,20 +82,21 @@ void analyseIfStmt(IfStmtNode *node, const WalkItem &wi, WalkItem &wo) wo.checkNullVars.erase(node1->label); // need check what return present + return; } } else if (node->condition->nodeType == NE_EXPR) { // if (... != ..) - NeExprNode *eq = static_cast(node->condition); - // need atleast two operands for EQ_EXPR node - if (eq->args.size() < 2) + NeExprNode *ne = static_cast(node->condition); + // need atleast two operands for NE_EXPR node + if (ne->args.size() < 2) return; // PARM_DECL? - Node *node1 = eq->args[0]; + Node *node1 = ne->args[0]; // INTEGER_CST? - Node *node2 = eq->args[1]; - // if (var != const) + Node *node2 = ne->args[1]; + // if (var != 0) if (node1->nodeType == PARM_DECL && node2->nodeType == INTEGER_CST && wi.checkNullVars.find(node1->label) != wi.checkNullVars.end() && @@ -104,13 +108,21 @@ void analyseIfStmt(IfStmtNode *node, const WalkItem &wi, WalkItem &wo) wi2.checkNullVars.erase(node1->label); // From then branch remove variable what we just found. walkTree(node->thenNode, wi2, wo); + wo.removeNullVars.clear(); wi2 = wi; // walking else node with all variables walkTree(node->elseNode, wi2, wo); + wo.removeNullVars.clear(); wo.stopWalking = true; return; } } + + // default case + walkTree(node->thenNode, wi, wo); + walkTree(node->elseNode, wi, wo); + wo.removeNullVars.clear(); + wo.stopWalking = true; } } -- cgit v1.2.3-60-g2f50