summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2015-06-18 17:28:59 +0300
committerAndrei Karas <akaras@inbox.ru>2015-06-18 17:28:59 +0300
commit4125da9e48ff0f6240ad705d8a47323b70ee59c1 (patch)
tree5d5b630f13419296fb8ca94167b78a33ef842c5b
parentd2b4c53238a9c455eb15d58526b7e5f43100f457 (diff)
downloadparanucker-4125da9e48ff0f6240ad705d8a47323b70ee59c1.tar.gz
paranucker-4125da9e48ff0f6240ad705d8a47323b70ee59c1.tar.bz2
paranucker-4125da9e48ff0f6240ad705d8a47323b70ee59c1.tar.xz
paranucker-4125da9e48ff0f6240ad705d8a47323b70ee59c1.zip
Improve analysis for nodes EQ_EXPR, NE_EXPR, TRUTH_ORIF_EXPR (incomplete).
-rw-r--r--src/analysis/analysis.cpp8
-rw-r--r--src/analysis/analysis.h2
-rw-r--r--src/analysis/expression.cpp29
-rw-r--r--src/analysis/statement.cpp10
-rw-r--r--src/analysis/walkitem.h13
-rw-r--r--src/logger.cpp28
-rw-r--r--src/logger.h9
7 files changed, 87 insertions, 12 deletions
diff --git a/src/analysis/analysis.cpp b/src/analysis/analysis.cpp
index ecdb079..caca286 100644
--- a/src/analysis/analysis.cpp
+++ b/src/analysis/analysis.cpp
@@ -141,6 +141,14 @@ Node *skipNop(Node *node)
return node;
}
+void mergeChecked(WalkItem &wi1, WalkItem &wi2)
+{
+ wi1.checkedNullVars.insert(wi2.checkedNullVars.begin(),
+ wi2.checkedNullVars.end());
+ wi1.checkedNonNullVars.insert(wi2.checkedNonNullVars.begin(),
+ wi2.checkedNonNullVars.end());
+}
+
void analyseNode(Node *node, const WalkItem &wi, WalkItem &wo)
{
if (!node)
diff --git a/src/analysis/analysis.h b/src/analysis/analysis.h
index df954b2..7215850 100644
--- a/src/analysis/analysis.h
+++ b/src/analysis/analysis.h
@@ -42,6 +42,8 @@ namespace Analysis
void removeCheckNullVars(WalkItem &wi);
Node *skipNop(Node *node);
+
+ void mergeChecked(WalkItem &wi1, WalkItem &wi2);
}
#endif // ANALYSIS_ANALYSIS_H
diff --git a/src/analysis/expression.cpp b/src/analysis/expression.cpp
index c057f88..0228f4b 100644
--- a/src/analysis/expression.cpp
+++ b/src/analysis/expression.cpp
@@ -83,9 +83,10 @@ void analyseReturnExpr(ReturnExprNode *node, const WalkItem &wi, WalkItem &wo)
void analyseNeExpr(NeExprNode *node, const WalkItem &wi, WalkItem &wo)
{
// need two args for check
- if (node->args.size() < 2 || !wi.isExpr || command == FindArgs)
+ if (node->args.size() < 2 || command == FindArgs)
return;
+ Log::log("analyseNeExpr 1\n");
// PARM_DECL?
Node *node1 = skipNop(node->args[0]);
// INTEGER_CST?
@@ -99,18 +100,18 @@ void analyseNeExpr(NeExprNode *node, const WalkItem &wi, WalkItem &wo)
wi.checkNullVars.find(node1->label) != wi.checkNullVars.end() &&
node2->label == "0")
{
- wo.removeNullVars.insert(node1->label);
- wo.checkNullVars.erase(node1->label);
+ Log::log("analyseNeExpr 2\n");
+ wo.checkedNonNullVars.insert(node1->label);
}
}
void analyseEqExpr(EqExprNode *node, const WalkItem &wi, WalkItem &wo)
{
// need two args for check
- if (node->args.size() < 2 || !wi.isExpr || command == FindArgs)
+ if (node->args.size() < 2 || command == FindArgs)
return;
-/*
+ Log::log("analyseEqExpr 1\n");
// PARM_DECL?
Node *node1 = skipNop(node->args[0]);
// INTEGER_CST?
@@ -123,13 +124,27 @@ void analyseEqExpr(EqExprNode *node, const WalkItem &wi, WalkItem &wo)
wi.checkNullVars.find(node1->label) != wi.checkNullVars.end() &&
node2->label == "0")
{
+ Log::log("analyseEqExpr 2\n");
+ wo.checkedNullVars.insert(node1->label);
}
-*/
-// do nothing for now
}
void analyseTruthOrIfExpr(TruthOrIfExprNode *node, const WalkItem &wi, WalkItem &wo)
{
+ // need two args for check
+ if (node->args.size() < 2 || command == FindArgs)
+ return;
+
+ Log::dumpWI(node, "wo ", wo);
+ WalkItem wo1 = wo;
+ WalkItem wo2 = wo;
+ walkTree(node->args[0], wi, wo1);
+ walkTree(node->args[1], wi, wo2);
+ Log::dumpWI(node, "wo1 ", wo1);
+ Log::dumpWI(node, "wo2 ", wo2);
+ mergeChecked(wo, wo1);
+ mergeChecked(wo, wo2);
+ wo.stopWalking = true;
}
}
diff --git a/src/analysis/statement.cpp b/src/analysis/statement.cpp
index 394dcfe..4366e2c 100644
--- a/src/analysis/statement.cpp
+++ b/src/analysis/statement.cpp
@@ -48,6 +48,16 @@ void analyseIfStmt(IfStmtNode *node, const WalkItem &wi, WalkItem &wo)
return;
Node *condNode = skipNop(node->condition);
+
+ // for now for debug
+ WalkItem wci = wi;
+ WalkItem wco = wo;
+ wci.isExpr = true;
+ walkTree(condNode, wci, wco);
+ Log::dumpWI(node, "wco ", wco);
+ // for now for debug
+
+
if (condNode->nodeType == EQ_EXPR)
{ // if (... == ..)
EqExprNode *eq = static_cast<EqExprNode*>(condNode);
diff --git a/src/analysis/walkitem.h b/src/analysis/walkitem.h
index 29352c0..11245bf 100644
--- a/src/analysis/walkitem.h
+++ b/src/analysis/walkitem.h
@@ -28,22 +28,27 @@ struct WalkItem
WalkItem() :
checkNullVars(),
removeNullVars(),
+ checkedNullVars(),
+ checkedNonNullVars(),
stopWalking(false),
- isReturned(false),
- isExpr(false)
+ isReturned(false)
{
}
WalkItem(const WalkItem &item) :
checkNullVars(item.checkNullVars),
removeNullVars(item.removeNullVars),
+ checkedNullVars(item.checkedNullVars),
+ checkedNonNullVars(item.checkedNonNullVars),
stopWalking(item.stopWalking),
isReturned(item.isReturned)
{
}
- std::set<std::string> checkNullVars;
- std::set<std::string> removeNullVars;
+ 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> 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
bool isReturned; // set if return present in child nodes
bool isExpr; // set if walking on expression for if other kind nodes
diff --git a/src/logger.cpp b/src/logger.cpp
index 1203c78..dbe1090 100644
--- a/src/logger.cpp
+++ b/src/logger.cpp
@@ -22,8 +22,12 @@
#include "command.h"
#include "includes.h"
+#include "analysis/walkitem.h"
+
#include "nodes/base/node.h"
+#include <set>
+
#include "localconsts.h"
namespace Log
@@ -188,6 +192,30 @@ void dumpAttr(const Node *const node, int num, bool isReturned)
fprintf(stderr, " walkTree%d: %d\n", num, isReturned ? 1 : 0);
}
+void dumpWI(Node *const node,
+ const std::string &name,
+ WalkItem &wi)
+{
+ Log::log("%s%s %s checkedNullVars:",
+ name.c_str(),
+ node->nodeTypeName.c_str(),
+ node->label.c_str());
+ FOR_EACH (std::set<std::string>::const_iterator,
+ it,
+ wi.checkedNullVars)
+ {
+ Log::log("%s, ", (*it).c_str());
+ }
+ Log::log(" checkedNonNullVars:");
+ FOR_EACH (std::set<std::string>::const_iterator,
+ it,
+ wi.checkedNonNullVars)
+ {
+ Log::log("%s, ", (*it).c_str());
+ }
+ Log::log("\n");
+}
+
void warn(const int loc,
const std::string &message,
const std::string &param)
diff --git a/src/logger.h b/src/logger.h
index 8fca641..6e7e982 100644
--- a/src/logger.h
+++ b/src/logger.h
@@ -23,6 +23,7 @@
#include <string>
struct Node;
+struct WalkItem;
namespace Log
{
@@ -55,7 +56,13 @@ namespace Log
const std::string &message,
const std::string &param);
- void dumpAttr(const Node *const node, int num, bool isReturned);
+ void dumpAttr(const Node *const node,
+ int num,
+ bool isReturned);
+
+ void dumpWI(Node *const node,
+ const std::string &name,
+ WalkItem &wi);
}
#endif // LOGGER_H