summaryrefslogtreecommitdiff
path: root/src/analysis/expression.cpp
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 /src/analysis/expression.cpp
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
Diffstat (limited to 'src/analysis/expression.cpp')
-rw-r--r--src/analysis/expression.cpp58
1 files changed, 58 insertions, 0 deletions
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);
+}
+
}