diff options
-rw-r--r-- | src/analysis/analysis.cpp | 59 | ||||
-rw-r--r-- | src/analysis/analysis.h | 3 | ||||
-rw-r--r-- | src/analysis/expression.cpp | 26 | ||||
-rw-r--r-- | src/analysis/expression.h | 3 | ||||
-rw-r--r-- | src/analysis/statement.cpp | 8 | ||||
-rw-r--r-- | src/analysis/walkitem.h | 3 | ||||
-rw-r--r-- | src/logger.cpp | 9 | ||||
-rw-r--r-- | src/logger.h | 2 |
8 files changed, 103 insertions, 10 deletions
diff --git a/src/analysis/analysis.cpp b/src/analysis/analysis.cpp index 47b6c6b..3e4b91c 100644 --- a/src/analysis/analysis.cpp +++ b/src/analysis/analysis.cpp @@ -33,6 +33,7 @@ #include "nodes/decl/var_decl.h" #include "nodes/expr/addr_expr.h" +#include "nodes/expr/bind_expr.h" #include "nodes/expr/compound_expr.h" #include "nodes/expr/cond_expr.h" #include "nodes/expr/eq_expr.h" @@ -66,6 +67,14 @@ void removeCheckNullVars(WalkItem &wi) } } +void addCheckNullVars(WalkItem &wi, WalkItem &wo) +{ + FOR_EACH (std::set<std::string>::const_iterator, it, wi.addNullVars) + { + wo.checkNullVars.insert(*it); + } +} + void removeCheckNullVarsSet(WalkItem &wi, std::set<std::string> &vars) { FOR_EACH (std::set<std::string>::const_iterator, it, vars) @@ -93,6 +102,8 @@ void walkTree(Node *node, const WalkItem &wi, WalkItem &wo) WalkItem wi2 = wi; analyseNode(node, wi2, wo); removeCheckNullVars(wi2); + addCheckNullVars(wo, wi2); + addCheckNullVars(wi2, wi2); // Log::dumpAttr(node, 1, wo.isReturned); const bool isReturned = wo.isReturned; @@ -107,10 +118,12 @@ void walkTree(Node *node, const WalkItem &wi, WalkItem &wo) { walkTree(*it, wi2, wo2); wi2.removeNullVars = wo2.removeNullVars; + wi2.addNullVars = wo2.addNullVars; wi2.isReturned = wi2.isReturned || wo2.isReturned; wo2.stopWalking = false; } wo.removeNullVars = wi2.removeNullVars; + wo.addNullVars = wi2.addNullVars; wo.isReturned = wo.isReturned || isReturned || wo2.isReturned; // Log::dumpAttr(node, 2, wo.isReturned); @@ -127,18 +140,39 @@ int findBackLocation(Node *node) return loc; } +bool checkForReport(Node *node, + const WalkItem &wi) +{ + node = skipNop(node); + return node && + node->nodeType == PARM_DECL && + wi.checkNullVars.find(node->label) != wi.checkNullVars.end(); +} + void reportParmDeclNullPointer(Node *mainNode, Node *node, const WalkItem &wi) { node = skipNop(node); - if (node && node->nodeType == PARM_DECL) + if (node) { - if (wi.checkNullVars.find(node->label) != wi.checkNullVars.end()) + if (node->nodeType == PARM_DECL) { - Log::warn(findBackLocation(mainNode), - "Using parameter '%s' without checking for null pointer", - node->label); + if (wi.checkNullVars.find(node->label) != wi.checkNullVars.end()) + { + Log::warn(findBackLocation(mainNode), + "Using parameter '%s' without checking for null pointer", + node->label); + } + } + if (node->nodeType == VAR_DECL) + { + if (wi.checkNullVars.find(node->label) != wi.checkNullVars.end()) + { + Log::warn(findBackLocation(mainNode), + "Using variable '%s' without checking for null pointer", + node->label); + } } } } @@ -208,6 +242,10 @@ void analyseNode(Node *node, const WalkItem &wi, WalkItem &wo) } Log::log("\n"); } + else + { + Log::dumpWI(node, "analyseNode wi in ", wi); + } WalkItem wi2 = wi; wo = wi; @@ -215,7 +253,13 @@ void analyseNode(Node *node, const WalkItem &wi, WalkItem &wo) // 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); +// addCheckNullVars(wi2); + } + + if (command != Command::DumpNullPointers) + Log::dumpWI(node, "analyseNode wi2 ", wi2); // searching function declaration switch (node->nodeType) @@ -226,6 +270,9 @@ void analyseNode(Node *node, const WalkItem &wi, WalkItem &wo) case ADDR_EXPR: analyseAddrExpr(static_cast<AddrExprNode*>(node), wi2, wo); break; + case BIND_EXPR: + analyseBindExpr(static_cast<BindExprNode*>(node), wi2, wo); + break; case MODIFY_EXPR: analyseModifyExpr(static_cast<ModifyExprNode*>(node), wi2, wo); break; @@ -265,6 +312,8 @@ void analyseNode(Node *node, const WalkItem &wi, WalkItem &wo) default: break; } + if (command != Command::DumpNullPointers) + Log::dumpWI(node, "analyseNode out ", wo); } } diff --git a/src/analysis/analysis.h b/src/analysis/analysis.h index 4d921cb..fe4bf67 100644 --- a/src/analysis/analysis.h +++ b/src/analysis/analysis.h @@ -42,6 +42,9 @@ namespace Analysis Node *node, const WalkItem &wi); + bool checkForReport(Node *node, + const WalkItem &wi); + void removeCheckNullVars(WalkItem &wi); void removeCheckNullVarsSet(WalkItem &wi, diff --git a/src/analysis/expression.cpp b/src/analysis/expression.cpp index be45955..b9bd9bc 100644 --- a/src/analysis/expression.cpp +++ b/src/analysis/expression.cpp @@ -26,6 +26,7 @@ #include "analysis/walkitem.h" #include "nodes/expr/addr_expr.h" +#include "nodes/expr/bind_expr.h" #include "nodes/expr/compound_expr.h" #include "nodes/expr/cond_expr.h" #include "nodes/expr/eq_expr.h" @@ -36,6 +37,8 @@ #include "nodes/expr/truthandif_expr.h" #include "nodes/expr/truthorif_expr.h" +#include "nodes/decl/var_decl.h" + #include "nodes/ref/indirect_ref.h" #include <set> @@ -341,4 +344,27 @@ void analyseCompoundExpr(CompoundExprNode *node, const WalkItem &wi, WalkItem &w Log::dumpWI(node, "wo out ", wo); } +// type var1 = var2; +void analyseBindExpr(BindExprNode *node, const WalkItem &wi, WalkItem &wo) +{ + // need one arg for check + if (node->args.empty() || command == FindArgs) + return; + + Log::dumpWI(node, "wo in ", wo); + Node *node1 = skipNop(node->args[0]); + + if (node1 && + node1->nodeType == VAR_DECL) + { + VarDeclNode *varDecl = static_cast<VarDeclNode*>(node1); + Node *initial = varDecl->initial; + if (checkForReport(initial, wi)) + { + wo.addNullVars.insert(varDecl->label); + } + } + Log::dumpWI(node, "wo out ", wo); +} + } diff --git a/src/analysis/expression.h b/src/analysis/expression.h index 94dcd47..bf906c7 100644 --- a/src/analysis/expression.h +++ b/src/analysis/expression.h @@ -23,6 +23,7 @@ #include "includes.h" struct AddrExprNode; +struct BindExprNode; struct CompoundExprNode; struct CondExprNode; struct EqExprNode; @@ -55,6 +56,8 @@ namespace Analysis void analyseCondExpr(CondExprNode *node, const WalkItem &wi, WalkItem &wo); void analyseCompoundExpr(CompoundExprNode *node, const WalkItem &wi, WalkItem &wo); + + void analyseBindExpr(BindExprNode *node, const WalkItem &wi, WalkItem &wo); } #endif // ANALYSIS_EXPRESSION_H diff --git a/src/analysis/statement.cpp b/src/analysis/statement.cpp index ef1cac2..50d9dc2 100644 --- a/src/analysis/statement.cpp +++ b/src/analysis/statement.cpp @@ -61,10 +61,12 @@ void analyseIfStmt(IfStmtNode *node, const WalkItem &wi, WalkItem &wo) { wi2.checkNullVars.erase(*it); } - std::set<std::string> tmpVars = wo.removeNullVars; + std::set<std::string> tmpRemove = wo.removeNullVars; + std::set<std::string> tmpAdd = wo.addNullVars; walkTree(node->thenNode, wi2, wo); wo.removeNullVars.clear(); + wo.addNullVars.clear(); const bool returned = wo.isReturned; wo.isReturned = false; @@ -77,7 +79,8 @@ void analyseIfStmt(IfStmtNode *node, const WalkItem &wi, WalkItem &wo) } walkTree(node->elseNode, wi2, wo); - wo.removeNullVars = tmpVars; + wo.removeNullVars = tmpRemove; + wo.addNullVars = tmpAdd; // if (returned && wco.cleanExpr && !wco.uselessExpr) if (returned && !wco.uselessExpr) @@ -117,7 +120,6 @@ void analyseIfStmt(IfStmtNode *node, const WalkItem &wi, WalkItem &wo) wo.stopWalking = true; wo.isReturned = false; - } } diff --git a/src/analysis/walkitem.h b/src/analysis/walkitem.h index 585d196..046ece0 100644 --- a/src/analysis/walkitem.h +++ b/src/analysis/walkitem.h @@ -28,6 +28,7 @@ struct WalkItem WalkItem() : checkNullVars(), removeNullVars(), + addNullVars(), checkedNullVars(), checkedNonNullVars(), stopWalking(false), @@ -40,6 +41,7 @@ struct WalkItem WalkItem(const WalkItem &item) : checkNullVars(item.checkNullVars), removeNullVars(item.removeNullVars), + addNullVars(item.addNullVars), checkedNullVars(item.checkedNullVars), checkedNonNullVars(item.checkedNonNullVars), stopWalking(item.stopWalking), @@ -51,6 +53,7 @@ struct WalkItem 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> addNullVars; // need add vars to 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 diff --git a/src/logger.cpp b/src/logger.cpp index b8bb00b..1a1428d 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -194,7 +194,7 @@ void dumpAttr(const Node *const node, int num, bool isReturned) void dumpWI(Node *const node, const std::string &name, - WalkItem &wi) + const WalkItem &wi) { return; Log::log("%s%s %s", @@ -235,6 +235,13 @@ void dumpWI(Node *const node, { Log::log("%s, ", (*it).c_str()); } + Log::log(" addNullVars:"); + FOR_EACH (std::set<std::string>::const_iterator, + it, + wi.addNullVars) + { + Log::log("%s, ", (*it).c_str()); + } Log::log("\n"); } diff --git a/src/logger.h b/src/logger.h index 6e7e982..d8237f8 100644 --- a/src/logger.h +++ b/src/logger.h @@ -62,7 +62,7 @@ namespace Log void dumpWI(Node *const node, const std::string &name, - WalkItem &wi); + const WalkItem &wi); } #endif // LOGGER_H |