summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2015-06-18 20:28:01 +0300
committerAndrei Karas <akaras@inbox.ru>2015-06-18 20:28:01 +0300
commit154855dc8d8ce6edf5ecd1bef8f0c9ce2b556e69 (patch)
tree5cbaa7507ad8c5c27a5d18c10800024cf0e9c267
parent4125da9e48ff0f6240ad705d8a47323b70ee59c1 (diff)
downloadparanucker-154855dc8d8ce6edf5ecd1bef8f0c9ce2b556e69.tar.gz
paranucker-154855dc8d8ce6edf5ecd1bef8f0c9ce2b556e69.tar.bz2
paranucker-154855dc8d8ce6edf5ecd1bef8f0c9ce2b556e69.tar.xz
paranucker-154855dc8d8ce6edf5ecd1bef8f0c9ce2b556e69.zip
Add basic analysis for node TRUTH_ANDIF_EXPR.
-rw-r--r--src/analysis/analysis.cpp4
-rw-r--r--src/analysis/expression.cpp42
-rw-r--r--src/analysis/expression.h3
-rw-r--r--src/analysis/statement.cpp1
-rw-r--r--src/analysis/walkitem.h8
-rw-r--r--src/logger.cpp5
6 files changed, 56 insertions, 7 deletions
diff --git a/src/analysis/analysis.cpp b/src/analysis/analysis.cpp
index caca286..0deb2df 100644
--- a/src/analysis/analysis.cpp
+++ b/src/analysis/analysis.cpp
@@ -39,6 +39,7 @@
#include "nodes/expr/nop_expr.h"
#include "nodes/expr/pointerplus_expr.h"
#include "nodes/expr/return_expr.h"
+#include "nodes/expr/truthandif_expr.h"
#include "nodes/expr/truthorif_expr.h"
#include "nodes/ref/component_ref.h"
@@ -197,6 +198,9 @@ void analyseNode(Node *node, const WalkItem &wi, WalkItem &wo)
case TRUTH_ORIF_EXPR:
analyseTruthOrIfExpr(static_cast<TruthOrIfExprNode*>(node), wi2, wo);
break;
+ case TRUTH_ANDIF_EXPR:
+ analyseTruthAndIfExpr(static_cast<TruthAndIfExprNode*>(node), wi2, wo);
+ break;
case RETURN_EXPR:
analyseReturnExpr(static_cast<ReturnExprNode*>(node), wi2, wo);
break;
diff --git a/src/analysis/expression.cpp b/src/analysis/expression.cpp
index 0228f4b..c81378f 100644
--- a/src/analysis/expression.cpp
+++ b/src/analysis/expression.cpp
@@ -31,6 +31,7 @@
#include "nodes/expr/ne_expr.h"
#include "nodes/expr/pointerplus_expr.h"
#include "nodes/expr/return_expr.h"
+#include "nodes/expr/truthandif_expr.h"
#include "nodes/expr/truthorif_expr.h"
#include "nodes/ref/indirect_ref.h"
@@ -102,6 +103,11 @@ void analyseNeExpr(NeExprNode *node, const WalkItem &wi, WalkItem &wo)
{
Log::log("analyseNeExpr 2\n");
wo.checkedNonNullVars.insert(node1->label);
+ wo.cleanExpr = true;
+ }
+ else
+ {
+ wo.cleanExpr = false;
}
}
@@ -126,6 +132,11 @@ void analyseEqExpr(EqExprNode *node, const WalkItem &wi, WalkItem &wo)
{
Log::log("analyseEqExpr 2\n");
wo.checkedNullVars.insert(node1->label);
+ wo.cleanExpr = true;
+ }
+ else
+ {
+ wo.cleanExpr = false;
}
}
@@ -142,9 +153,36 @@ void analyseTruthOrIfExpr(TruthOrIfExprNode *node, const WalkItem &wi, WalkItem
walkTree(node->args[1], wi, wo2);
Log::dumpWI(node, "wo1 ", wo1);
Log::dumpWI(node, "wo2 ", wo2);
- mergeChecked(wo, wo1);
- mergeChecked(wo, wo2);
+ if (wo1.cleanExpr)
+ mergeChecked(wo, wo1);
+ if (wo2.cleanExpr)
+ mergeChecked(wo, wo2);
+ wo.cleanExpr = true;
wo.stopWalking = true;
}
+void analyseTruthAndIfExpr(TruthAndIfExprNode *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;
+ walkTree(node->args[0], wi, wo1);
+ WalkItem wo2 = wo1;
+ walkTree(node->args[1], wo1, wo2);
+ Log::dumpWI(node, "wo1 ", wo1);
+ Log::dumpWI(node, "wo2 ", wo2);
+
+ wo.stopWalking = true;
+ if (wo1.cleanExpr && wo2.cleanExpr)
+ { // need combine wo1 and wo2
+ // for now empty simple merge, but must be compilated!
+ mergeChecked(wo, wo1);
+ mergeChecked(wo, wo2);
+ }
+ wo.cleanExpr = true;
+}
+
}
diff --git a/src/analysis/expression.h b/src/analysis/expression.h
index 9d2aef8..b7851fd 100644
--- a/src/analysis/expression.h
+++ b/src/analysis/expression.h
@@ -28,6 +28,7 @@ struct ModifyExprNode;
struct NeExprNode;
struct PointerPlusExprNode;
struct ReturnExprNode;
+struct TruthAndIfExprNode;
struct TruthOrIfExprNode;
struct WalkItem;
@@ -46,6 +47,8 @@ namespace Analysis
void analyseEqExpr(EqExprNode *node, const WalkItem &wi, WalkItem &wo);
void analyseTruthOrIfExpr(TruthOrIfExprNode *node, const WalkItem &wi, WalkItem &wo);
+
+ void analyseTruthAndIfExpr(TruthAndIfExprNode *node, const WalkItem &wi, WalkItem &wo);
}
#endif // ANALYSIS_EXPRESSION_H
diff --git a/src/analysis/statement.cpp b/src/analysis/statement.cpp
index 4366e2c..24f1080 100644
--- a/src/analysis/statement.cpp
+++ b/src/analysis/statement.cpp
@@ -52,7 +52,6 @@ void analyseIfStmt(IfStmtNode *node, const WalkItem &wi, WalkItem &wo)
// 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
diff --git a/src/analysis/walkitem.h b/src/analysis/walkitem.h
index 11245bf..fc33049 100644
--- a/src/analysis/walkitem.h
+++ b/src/analysis/walkitem.h
@@ -31,7 +31,8 @@ struct WalkItem
checkedNullVars(),
checkedNonNullVars(),
stopWalking(false),
- isReturned(false)
+ isReturned(false),
+ cleanExpr(false)
{
}
@@ -41,7 +42,8 @@ struct WalkItem
checkedNullVars(item.checkedNullVars),
checkedNonNullVars(item.checkedNonNullVars),
stopWalking(item.stopWalking),
- isReturned(item.isReturned)
+ isReturned(item.isReturned),
+ cleanExpr(item.cleanExpr)
{
}
@@ -51,7 +53,7 @@ struct WalkItem
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
+ bool cleanExpr; // set if expression is only variable check without compound conditions
};
diff --git a/src/logger.cpp b/src/logger.cpp
index dbe1090..23cb32d 100644
--- a/src/logger.cpp
+++ b/src/logger.cpp
@@ -196,10 +196,13 @@ void dumpWI(Node *const node,
const std::string &name,
WalkItem &wi)
{
- Log::log("%s%s %s checkedNullVars:",
+ Log::log("%s%s %s",
name.c_str(),
node->nodeTypeName.c_str(),
node->label.c_str());
+ if (wi.cleanExpr)
+ Log::log(" clean");
+ Log::log(" checkedNullVars:");
FOR_EACH (std::set<std::string>::const_iterator,
it,
wi.checkedNullVars)