summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/analysis/analysis.cpp59
-rw-r--r--src/analysis/analysis.h3
-rw-r--r--src/analysis/expression.cpp26
-rw-r--r--src/analysis/expression.h3
-rw-r--r--src/analysis/statement.cpp8
-rw-r--r--src/analysis/walkitem.h3
-rw-r--r--src/logger.cpp9
-rw-r--r--src/logger.h2
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