diff options
author | Andrei Karas <akaras@inbox.ru> | 2015-06-20 21:56:46 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2015-06-20 21:56:46 +0300 |
commit | c3127a8378c7322d09317c72c6a2178f48e59bbf (patch) | |
tree | c46234150422555dc117622fccd626dedea05f26 /src/analysis/expression.cpp | |
parent | f9297a22459a24b6909d89bd5491f9e76062b82a (diff) | |
download | paranucker-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.cpp | 58 |
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); +} + } |