summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2015-06-20 21:56:46 +0300
committerAndrei Karas <akaras@inbox.ru>2015-06-20 21:56:46 +0300
commitc3127a8378c7322d09317c72c6a2178f48e59bbf (patch)
treec46234150422555dc117622fccd626dedea05f26
parentf9297a22459a24b6909d89bd5491f9e76062b82a (diff)
downloadparanucker-c3127a8378c7322d09317c72c6a2178f48e59bbf.tar.gz
paranucker-c3127a8378c7322d09317c72c6a2178f48e59bbf.tar.bz2
paranucker-c3127a8378c7322d09317c72c6a2178f48e59bbf.tar.xz
paranucker-c3127a8378c7322d09317c72c6a2178f48e59bbf.zip
Add analysis for node COND_EXPR.
This allow check expressions like: expr ? expr : expr
-rw-r--r--src/analysis/analysis.cpp4
-rw-r--r--src/analysis/expression.cpp58
-rw-r--r--src/analysis/expression.h3
3 files changed, 65 insertions, 0 deletions
diff --git a/src/analysis/analysis.cpp b/src/analysis/analysis.cpp
index 8352971..e31a393 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/cond_expr.h"
#include "nodes/expr/eq_expr.h"
#include "nodes/expr/modify_expr.h"
#include "nodes/expr/ne_expr.h"
@@ -233,6 +234,9 @@ void analyseNode(Node *node, const WalkItem &wi, WalkItem &wo)
case EQ_EXPR:
analyseEqExpr(static_cast<EqExprNode*>(node), wi2, wo);
break;
+ case COND_EXPR:
+ analyseCondExpr(static_cast<CondExprNode*>(node), wi2, wo);
+ break;
case TRUTH_ORIF_EXPR:
analyseTruthOrIfExpr(static_cast<TruthOrIfExprNode*>(node), wi2, wo);
break;
diff --git a/src/analysis/expression.cpp b/src/analysis/expression.cpp
index 506aef4..c3d97cf 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/cond_expr.h"
#include "nodes/expr/eq_expr.h"
#include "nodes/expr/modify_expr.h"
#include "nodes/expr/ne_expr.h"
@@ -209,4 +210,61 @@ void analyseTruthAndIfExpr(TruthAndIfExprNode *node, const WalkItem &wi, WalkIte
Log::dumpWI(node, "wo out ", wo);
}
+// args[0] condition
+// args[1] true expr
+// args[2] false expr
+void analyseCondExpr(CondExprNode *node, const WalkItem &wi, WalkItem &wo)
+{
+ // need tree args for check
+ if (node->args.size() < 3 || command == FindArgs)
+ return;
+
+ Log::dumpWI(node, "wo in ", wo);
+ WalkItem wo1 = wo;
+ WalkItem wo2 = wo;
+ WalkItem wo3 = wo;
+
+ // walk condition
+ walkTree(node->args[0], wi, wo1);
+ Log::dumpWI(node, "wo1 ", wo1);
+ WalkItem wi2 = wi;
+ removeCheckNullVarsSet(wi2, wo1.checkedNonNullVars);
+ wi2.checkNullVars.insert(wo1.checkedNullVars.begin(),
+ wo1.checkedNullVars.end());
+ Log::dumpWI(node, "wi2 ", wi2);
+
+ reportParmDeclNullPointer(node,
+ node->args[1],
+ wi2);
+ // walk true expr
+ walkTree(node->args[1], wi2, wo2);
+ Log::dumpWI(node, "wo2 ", wo2);
+ WalkItem wi3 = wi;
+ removeCheckNullVarsSet(wi3, wo1.checkedNullVars);
+ wi3.checkNullVars.insert(wo1.checkedNonNullVars.begin(),
+ wo1.checkedNonNullVars.end());
+ Log::dumpWI(node, "wi3 ", wi3);
+
+ reportParmDeclNullPointer(node,
+ node->args[2],
+ wi3);
+ // walk true expr
+ walkTree(node->args[2], wi3, wo3);
+ Log::dumpWI(node, "wo3 ", wo3);
+
+ // probably condition wrong
+ if (wo2.cleanExpr)
+ mergeNullChecked(wo, wo2);
+ // probably condition wrong
+ if (wo3.cleanExpr)
+ mergeNullChecked(wo, wo3);
+ // need check for cleanExpr?
+ intersectNonNullChecked(wo, wo2, wo3);
+
+ wo.cleanExpr = true;
+ wo.stopWalking = true;
+ wo.uselessExpr = false;
+ Log::dumpWI(node, "wo out ", wo);
+}
+
}
diff --git a/src/analysis/expression.h b/src/analysis/expression.h
index b7851fd..8e64ec5 100644
--- a/src/analysis/expression.h
+++ b/src/analysis/expression.h
@@ -23,6 +23,7 @@
#include "includes.h"
struct AddrExprNode;
+struct CondExprNode;
struct EqExprNode;
struct ModifyExprNode;
struct NeExprNode;
@@ -49,6 +50,8 @@ namespace Analysis
void analyseTruthOrIfExpr(TruthOrIfExprNode *node, const WalkItem &wi, WalkItem &wo);
void analyseTruthAndIfExpr(TruthAndIfExprNode *node, const WalkItem &wi, WalkItem &wo);
+
+ void analyseCondExpr(CondExprNode *node, const WalkItem &wi, WalkItem &wo);
}
#endif // ANALYSIS_EXPRESSION_H