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 | |
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
-rw-r--r-- | src/analysis/analysis.cpp | 4 | ||||
-rw-r--r-- | src/analysis/expression.cpp | 58 | ||||
-rw-r--r-- | src/analysis/expression.h | 3 |
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 |