summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2015-07-23 02:14:15 +0300
committerAndrei Karas <akaras@inbox.ru>2015-07-23 02:14:15 +0300
commiteff039b810786f96ed8f0bade95ff07a7c4e15dd (patch)
treefa6f647e298446f0a9744b363a5e3d2d73eb76b6 /src
parentd334657133cb123b79e5998c151b5285fc204018 (diff)
downloadparanucker-eff039b810786f96ed8f0bade95ff07a7c4e15dd.tar.gz
paranucker-eff039b810786f96ed8f0bade95ff07a7c4e15dd.tar.bz2
paranucker-eff039b810786f96ed8f0bade95ff07a7c4e15dd.tar.xz
paranucker-eff039b810786f96ed8f0bade95ff07a7c4e15dd.zip
Remove null checks from COMPONENT_REF node. But add check in different parent nodes.
Diffstat (limited to 'src')
-rw-r--r--src/analysis/analysis.cpp4
-rw-r--r--src/analysis/expression.cpp95
-rw-r--r--src/analysis/expression.h6
-rw-r--r--src/analysis/ref.cpp15
-rw-r--r--src/analysis/ref.h2
-rw-r--r--src/analysis/reports.cpp73
-rw-r--r--src/analysis/reports.h8
-rw-r--r--src/analysis/statement.cpp2
8 files changed, 195 insertions, 10 deletions
diff --git a/src/analysis/analysis.cpp b/src/analysis/analysis.cpp
index 32c0170..50f9211 100644
--- a/src/analysis/analysis.cpp
+++ b/src/analysis/analysis.cpp
@@ -53,6 +53,7 @@
#include "nodes/expr/truthor_expr.h"
#include "nodes/expr/truthorif_expr.h"
+#include "nodes/ref/array_ref.h"
#include "nodes/ref/component_ref.h"
#include "nodes/stmt/break_stmt.h"
@@ -291,6 +292,9 @@ void analyseNode(Node *node, const WalkItem &wi, WalkItem &wo)
case CONTINUE_STMT:
analyseContinueStmt(static_cast<ContinueStmtNode*>(node), wi2, wo);
break;
+ case ARRAY_REF:
+ analyseArrayRef(static_cast<ArrayRefNode*>(node), wi2, wo);
+ break;
case COMPONENT_REF:
analyseComponentRef(static_cast<ComponentRefNode*>(node), wi2, wo);
break;
diff --git a/src/analysis/expression.cpp b/src/analysis/expression.cpp
index 3877d68..7370a57 100644
--- a/src/analysis/expression.cpp
+++ b/src/analysis/expression.cpp
@@ -60,6 +60,7 @@
#include "nodes/ref/indirect_ref.h"
#include "nodes/ref/objtype_ref.h"
+#include "nodes/type/array_type.h"
#include "nodes/type/method_type.h"
#include <set>
@@ -141,6 +142,78 @@ std::string getComponentRefVariable(Node *node)
return str;
}
+std::vector<std::string> getComponentRefParts(Node *node)
+{
+ std::vector<std::string> str;
+ ComponentRefNode *const comp = static_cast<ComponentRefNode*>(skipNop(node));
+ if (comp &&
+ comp->object &&
+ comp->field)
+ {
+ Node *object = skipNop(comp->object);
+ Node *field = skipNop(comp->field);
+ if (object == INDIRECT_REF &&
+ field == FIELD_DECL)
+ {
+ FieldDeclNode *fieldDecl = static_cast<FieldDeclNode*>(field);
+ IndirectRefNode *indirect = static_cast<IndirectRefNode*>(object);
+ Node *ref = skipNop(indirect->ref);
+ if (ref == PARM_DECL)
+ {
+ ParmDeclNode *parmDecl = static_cast<ParmDeclNode*>(ref);
+ if (parmDecl->declType == POINTER_TYPE)
+ str.push_back(ref->label);
+ }
+ if (ref == VAR_DECL)
+ {
+ VarDeclNode *varDecl = static_cast<VarDeclNode*>(ref);
+ if (varDecl->varType == POINTER_TYPE)
+ str.push_back(ref->label);
+ }
+ if (ref == PARM_DECL || ref == VAR_DECL)
+ {
+ if (skipNop(fieldDecl->fieldType) != POINTER_TYPE)
+ {
+ if (skipNop(fieldDecl->fieldType) != ARRAY_TYPE)
+ return str;
+ ArrayTypeNode *arr = static_cast<ArrayTypeNode*>(skipNop(fieldDecl->fieldType));
+ if (arr->elementType != POINTER_TYPE)
+ return str;
+ }
+ str.push_back(std::string(ref->label).append("->").append(field->label));
+ }
+ }
+ }
+ return str;
+}
+
+std::vector<std::string> getComponentRefLeftParts(Node *node)
+{
+ std::vector<std::string> str;
+ ComponentRefNode *const comp = static_cast<ComponentRefNode*>(skipNop(node));
+ if (comp &&
+ comp->object &&
+ comp->field)
+ {
+ Node *object = skipNop(comp->object);
+ Node *field = skipNop(comp->field);
+ if (object == INDIRECT_REF &&
+ field == FIELD_DECL)
+ {
+// FieldDeclNode *fieldDecl = static_cast<FieldDeclNode*>(field);
+// if (fieldDecl->fieldType != POINTER_TYPE)
+// return str;
+ IndirectRefNode *indirect = static_cast<IndirectRefNode*>(object);
+ Node *ref = skipNop(indirect->ref);
+ if (ref == PARM_DECL || ref == VAR_DECL)
+ {
+ str.push_back(ref->label);
+ }
+ }
+ }
+ return str;
+}
+
void analyseModifyExpr(ModifyExprNode *node, const WalkItem &wi, WalkItem &wo)
{
// need atleast one arg for check
@@ -159,15 +232,24 @@ void analyseModifyExpr(ModifyExprNode *node, const WalkItem &wi, WalkItem &wo)
ComponentRefNode *comp = static_cast<ComponentRefNode*>(arg);
if (skipNop(comp->object) == INDIRECT_REF)
arg0 = skipNop(comp->object);
+
+ if (arg0 == INDIRECT_REF)
+ {
+ // var2 not found in known checking pointer
+ reportParmDeclNullPointer(node,
+ static_cast<IndirectRefNode*>(arg0)->ref,
+ wi);
+ }
}
- if (arg0 == INDIRECT_REF)
+ if (arg == INDIRECT_REF)
{
// var2 not found in known checking pointer
reportParmDeclNullPointer(node,
- static_cast<IndirectRefNode*>(arg0)->ref,
+ static_cast<IndirectRefNode*>(arg)->ref,
wi);
- if (isNotIn(var2, wi.needCheckNullVars) &&
+ if (!var1.empty() &&
+ isNotIn(var2, wi.needCheckNullVars) &&
isNotIn(var2, wi.knownVars))
{
removeVar(wo, var1);
@@ -263,6 +345,9 @@ void analyseNeExpr(NeExprNode *node, const WalkItem &wi, WalkItem &wo)
// INTEGER_CST?
Node *node2 = skipNop(node->args[1]);
+ reportParmDeclLeftNullPointer(node, node1, wi);
+ reportParmDeclLeftNullPointer(node, node2, wi);
+
std::string var = getVariableName(node1);
// if (var != 0)
if (!var.empty() &&
@@ -375,6 +460,10 @@ void analyseEqExpr(EqExprNode *node, const WalkItem &wi, WalkItem &wo)
Node *node1 = skipNop(node->args[0]);
// INTEGER_CST?
Node *node2 = skipNop(node->args[1]);
+
+ reportParmDeclLeftNullPointer(node, node1, wi);
+ reportParmDeclLeftNullPointer(node, node2, wi);
+
std::string var = getVariableName(node1);
// if (var == 0)
if (!var.empty() &&
diff --git a/src/analysis/expression.h b/src/analysis/expression.h
index 9c42bd2..602a9ae 100644
--- a/src/analysis/expression.h
+++ b/src/analysis/expression.h
@@ -44,6 +44,8 @@ struct TruthOrExprNode;
struct TruthOrIfExprNode;
struct WalkItem;
+#include <vector>
+
namespace Analysis
{
void analyseModifyExpr(ModifyExprNode *node, const WalkItem &wi, WalkItem &wo);
@@ -95,6 +97,10 @@ namespace Analysis
std::string getComponentRefVariable(Node *node);
+ std::vector<std::string> getComponentRefParts(Node *node);
+
+ std::vector<std::string> getComponentRefLeftParts(Node *node);
+
bool handleSetVarToFunction(const std::string &var,
Node *node1,
Node *node2,
diff --git a/src/analysis/ref.cpp b/src/analysis/ref.cpp
index 4c8a4be..2391fa3 100644
--- a/src/analysis/ref.cpp
+++ b/src/analysis/ref.cpp
@@ -30,6 +30,7 @@
#include "nodes/expr/modify_expr.h"
#include "nodes/expr/pointerplus_expr.h"
+#include "nodes/ref/array_ref.h"
#include "nodes/ref/component_ref.h"
#include "nodes/ref/indirect_ref.h"
@@ -59,4 +60,18 @@ void analyseComponentRef(ComponentRefNode *node,
*/
}
+void analyseArrayRef(ArrayRefNode *node,
+ const WalkItem &wi,
+ WalkItem &wo A_UNUSED)
+{
+ // need atleast one arg for check
+ if (node->args.empty() || checkCommand(FindArgs))
+ return;
+
+ FOR_EACH(it, node->args)
+ {
+ reportParmDeclNullPointer(node, it, wi);
+ }
+}
+
}
diff --git a/src/analysis/ref.h b/src/analysis/ref.h
index ff245cc..608d033 100644
--- a/src/analysis/ref.h
+++ b/src/analysis/ref.h
@@ -22,12 +22,14 @@
#include "includes.h"
+struct ArrayRefNode;
struct ComponentRefNode;
struct WalkItem;
namespace Analysis
{
void analyseComponentRef(ComponentRefNode *node, const WalkItem &wi, WalkItem &wo);
+ void analyseArrayRef(ArrayRefNode *node, const WalkItem &wi, WalkItem &wo);
}
#endif // ANALYSIS_REF_H
diff --git a/src/analysis/reports.cpp b/src/analysis/reports.cpp
index af5806b..733171a 100644
--- a/src/analysis/reports.cpp
+++ b/src/analysis/reports.cpp
@@ -28,6 +28,9 @@
#include "nodes/base/node.h"
+#include "nodes/decl/parm_decl.h"
+#include "nodes/decl/var_decl.h"
+
#include "localconsts.h"
namespace Analysis
@@ -66,7 +69,9 @@ void reportParmDeclNullPointer(Node *mainNode,
{
if (node == PARM_DECL)
{
- if (isIn(node->label, wi.needCheckNullVars))
+ ParmDeclNode *parmDecl = static_cast<ParmDeclNode*>(node);
+ if (parmDecl->declType == POINTER_TYPE &&
+ isIn(node->label, wi.needCheckNullVars))
{
Log::warn(findBackLocation(mainNode),
"Using parameter '%s' without checking for null pointer",
@@ -75,7 +80,9 @@ void reportParmDeclNullPointer(Node *mainNode,
}
else if (node == VAR_DECL)
{
- if (isIn(node->label, wi.needCheckNullVars))
+ VarDeclNode *varDecl = static_cast<VarDeclNode*>(node);
+ if (varDecl->varType == POINTER_TYPE &&
+ isIn(node->label, wi.needCheckNullVars))
{
Log::warn(findBackLocation(mainNode),
"Using variable '%s' without checking for null pointer",
@@ -85,12 +92,64 @@ void reportParmDeclNullPointer(Node *mainNode,
}
else if (node == COMPONENT_REF)
{
- std::string var = getComponentRefVariable(node);
- if (isIn(var, wi.needCheckNullVars))
+ auto vars = getComponentRefParts(node);
+ FOR_EACH (var, vars)
{
- Log::warn(findBackLocation(mainNode),
- "Using field '%s' without checking for null pointer",
- var);
+ if (isIn(var, wi.needCheckNullVars) ||
+ isNotIn(var, wi.knownVars))
+ {
+ Log::warn(findBackLocation(mainNode),
+ "Using variable '%s' without checking for null pointer",
+ var);
+ }
+ }
+ }
+ }
+}
+
+// report about null pointer if need for node
+void reportParmDeclLeftNullPointer(Node *mainNode,
+ Node *node,
+ const WalkItem &wi)
+{
+ node = skipNop(node);
+ if (node)
+ {
+ if (node == COMPONENT_REF)
+ {
+ auto vars = getComponentRefLeftParts(node);
+ FOR_EACH (var, vars)
+ {
+ if (isIn(var, wi.needCheckNullVars))
+ {
+ Log::warn(findBackLocation(mainNode),
+ "Using field '%s' without checking for null pointer",
+ var);
+ }
+ }
+ }
+ }
+}
+
+// report about null pointer if need for node
+void reportComponentRefNullPointer(Node *mainNode,
+ Node *node,
+ const WalkItem &wi)
+{
+ node = skipNop(node);
+ if (node)
+ {
+ if (node == COMPONENT_REF)
+ {
+ auto vars = getComponentRefParts(node);
+ FOR_EACH (var, vars)
+ {
+ if (isIn(var, wi.needCheckNullVars))
+ {
+ Log::warn(findBackLocation(mainNode),
+ "Using field '%s' without checking for null pointer",
+ var);
+ }
}
}
}
diff --git a/src/analysis/reports.h b/src/analysis/reports.h
index 4278ee4..7f65fb8 100644
--- a/src/analysis/reports.h
+++ b/src/analysis/reports.h
@@ -34,6 +34,14 @@ namespace Analysis
Node *node,
const WalkItem &wi);
+ void reportParmDeclLeftNullPointer(Node *mainNode,
+ Node *node,
+ const WalkItem &wi);
+
+ void reportComponentRefNullPointer(Node *mainNode,
+ Node *node,
+ const WalkItem &wi);
+
void reportParmDeclAttrNullPointer(Node *mainNode,
Node *node,
const WalkItem &wi);
diff --git a/src/analysis/statement.cpp b/src/analysis/statement.cpp
index 5e6ea7a..a5aba2d 100644
--- a/src/analysis/statement.cpp
+++ b/src/analysis/statement.cpp
@@ -79,6 +79,7 @@ void analyseCondition(Node *node,
reportParmDeclNullPointer(node,
thenNode,
wi2);
+ reportParmDeclLeftNullPointer(node, thenNode, wi2);
walkTree(thenNode, wi2, wo2);
Log::dumpWI(node, "wo2 then ", wo2);
@@ -98,6 +99,7 @@ void analyseCondition(Node *node,
reportParmDeclNullPointer(node,
elseNode,
wi3);
+ reportParmDeclLeftNullPointer(node, elseNode, wi3);
walkTree(elseNode, wi3, wo3);
Log::dumpWI(node, "wo3 else ", wo3);