summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2015-06-11 23:42:07 +0300
committerAndrei Karas <akaras@inbox.ru>2015-06-11 23:42:07 +0300
commite8e75ca7639bf3a8e34391aaa33f90c18905e977 (patch)
tree5201e8207d73f89a8dede013ba5780d10a1b480b
parent23f9052202cac18045c1a49465ac765fbd155f56 (diff)
downloadparanucker-e8e75ca7639bf3a8e34391aaa33f90c18905e977.tar.gz
paranucker-e8e75ca7639bf3a8e34391aaa33f90c18905e977.tar.bz2
paranucker-e8e75ca7639bf3a8e34391aaa33f90c18905e977.tar.xz
paranucker-e8e75ca7639bf3a8e34391aaa33f90c18905e977.zip
Fix some issues in test6.
Now if variable check happend before other code variable will not trigger warning. Example: if (!a) return; *a = 10;
-rw-r--r--src/analysis/analysis.cpp40
-rw-r--r--src/analysis/analysis.h2
-rw-r--r--src/analysis/statement.cpp26
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<std::string>::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<std::string>::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<FunctionDeclNode*>(node), wi, wo);
+ analyseFunction(static_cast<FunctionDeclNode*>(node), wi2, wo);
break;
case ADDR_EXPR:
- analyseAddrExpr(static_cast<AddrExprNode*>(node), wi, wo);
+ analyseAddrExpr(static_cast<AddrExprNode*>(node), wi2, wo);
break;
case MODIFY_EXPR:
- analyseModifyExpr(static_cast<ModifyExprNode*>(node), wi, wo);
+ analyseModifyExpr(static_cast<ModifyExprNode*>(node), wi2, wo);
break;
case POINTER_PLUS_EXPR:
- analysePointerPlusExpr(static_cast<PointerPlusExprNode*>(node), wi, wo);
+ analysePointerPlusExpr(static_cast<PointerPlusExprNode*>(node), wi2, wo);
break;
case VAR_DECL:
- analyseVarDecl(static_cast<VarDeclNode*>(node), wi, wo);
+ analyseVarDecl(static_cast<VarDeclNode*>(node), wi2, wo);
break;
case IF_STMT:
- analyseIfStmt(static_cast<IfStmtNode*>(node), wi, wo);
+ analyseIfStmt(static_cast<IfStmtNode*>(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<NeExprNode*>(node->condition);
- // need atleast two operands for EQ_EXPR node
- if (eq->args.size() < 2)
+ NeExprNode *ne = static_cast<NeExprNode*>(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;
}
}