diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.files | 1 | ||||
-rw-r--r-- | src/analysis/expression.cpp | 151 | ||||
-rw-r--r-- | src/analysis/expression.h | 11 | ||||
-rw-r--r-- | src/analysis/reports.cpp | 19 | ||||
-rw-r--r-- | src/analysis/varitem.h | 47 |
5 files changed, 140 insertions, 89 deletions
diff --git a/src/Makefile.files b/src/Makefile.files index c6e126b..c2a7490 100644 --- a/src/Makefile.files +++ b/src/Makefile.files @@ -18,6 +18,7 @@ SRC = analysis/analysis.cpp \ analysis/reports.h \ analysis/statement.cpp \ analysis/statement.h \ + analysis/varitem.h \ analysis/walkitem.h \ nodes/base/cst.h \ nodes/base/decl.h \ diff --git a/src/analysis/expression.cpp b/src/analysis/expression.cpp index e64026c..fb7fa86 100644 --- a/src/analysis/expression.cpp +++ b/src/analysis/expression.cpp @@ -28,6 +28,7 @@ #include "analysis/function.h" #include "analysis/reports.h" #include "analysis/statement.h" +#include "analysis/varitem.h" #include "analysis/walkitem.h" #include "nodes/expr/addr_expr.h" @@ -72,14 +73,14 @@ namespace Analysis { // return variable name if possible or empty string -std::string getVariableName(Node *node) +VarItem getVariableName(Node *node) { if (!node) - return ""; + return VarItem(); node = skipNop(node); if (!node) - return ""; + return VarItem(); if (node == PARM_DECL) { @@ -87,22 +88,22 @@ std::string getVariableName(Node *node) if (skipNop(decl->declType) != nullptr && skipNop(decl->declType) != POINTER_TYPE) { - return ""; + return VarItem(); } - return node->label; + return VarItem(node->label); } if (node == VAR_DECL) { VarDeclNode *var = static_cast<VarDeclNode*>(node); if (skipNop(var->varType) != POINTER_TYPE) - return ""; - return node->label; + return VarItem(); + return VarItem(node->label); } else if (node == COMPONENT_REF) { return getComponentRefVariable(node); } - return ""; + return VarItem(); } bool isPointerArg(Node *node) @@ -136,9 +137,9 @@ bool isPointerArg(Node *node) } // return variable name in format object->field for component node -std::string getComponentRefVariable(Node *node) +VarItem getComponentRefVariable(Node *node) { - std::string str; + VarItem str; ComponentRefNode *const comp = static_cast<ComponentRefNode*>(skipNop(node)); if (comp && comp->object && @@ -181,23 +182,23 @@ std::string getComponentRefVariable(Node *node) { if (!isValidVar(field->label)) return str; - str.append(ref->label).append("->").append(field->label); + str.name.append(ref->label).append("->").append(field->label); } } } return str; } -bool isValidVar(const std::string &str) +bool isValidVar(const VarItem &str) { - if (str.size() > 6 && str.substr(0, 6) == "_vptr.") + if (str.size() > 6 && str.name.substr(0, 6) == "_vptr.") return false; return true; } -std::vector<std::string> getComponentRefParts(Node *node) +std::vector<VarItem> getComponentRefParts(Node *node) { - std::vector<std::string> str; + std::vector<VarItem> str; ComponentRefNode *const comp = static_cast<ComponentRefNode*>(skipNop(node)); if (comp && comp->object && @@ -225,14 +226,14 @@ std::vector<std::string> getComponentRefParts(Node *node) if (skipNop(parmDecl->declType) == nullptr || skipNop(parmDecl->declType) == POINTER_TYPE) { - str.push_back(ref->label); + str.push_back(VarItem(ref->label)); } } if (ref == VAR_DECL) { VarDeclNode *varDecl = static_cast<VarDeclNode*>(ref); if (varDecl->varType == POINTER_TYPE) - str.push_back(ref->label); + str.push_back(VarItem(ref->label)); } if (ref == PARM_DECL || ref == VAR_DECL) { @@ -246,16 +247,16 @@ std::vector<std::string> getComponentRefParts(Node *node) } if (!isValidVar(field->label)) return str; - str.push_back(std::string(ref->label).append("->").append(field->label)); + str.push_back(VarItem(std::string(ref->label).append("->").append(field->label))); } } } return str; } -std::vector<std::string> getComponentRefLeftParts(Node *node) +std::vector<VarItem> getComponentRefLeftParts(Node *node) { - std::vector<std::string> str; + std::vector<VarItem> str; ComponentRefNode *const comp = static_cast<ComponentRefNode*>(skipNop(node)); if (comp && comp->object && @@ -281,7 +282,7 @@ std::vector<std::string> getComponentRefLeftParts(Node *node) return str; if (ref == PARM_DECL || ref == VAR_DECL) { - str.push_back(ref->label); + str.push_back(VarItem(ref->label)); } } } @@ -297,8 +298,8 @@ void analyseModifyExpr(ModifyExprNode *node, const WalkItem &wi, WalkItem &wo) Node *arg = skipNop(node->args[0]); if (arg) { - std::string var1 = getVariableName(arg); - std::string var2 = getVariableName(node->args[1]); + VarItem var1 = getVariableName(arg); + VarItem var2 = getVariableName(node->args[1]); Node *arg0 = arg; if (arg == COMPONENT_REF) @@ -323,10 +324,10 @@ void analyseModifyExpr(ModifyExprNode *node, const WalkItem &wi, WalkItem &wo) wi); if (!var1.empty() && - isNotIn(var2, wi.needCheckNullVars) && - isNotIn(var2, wi.knownVars)) + isNotIn(var2.name, wi.needCheckNullVars) && + isNotIn(var2.name, wi.knownVars)) { - removeVar(wo, var1); + removeVar(wo, var1.name); } } else if (!var1.empty()) @@ -345,19 +346,19 @@ void analyseModifyExpr(ModifyExprNode *node, const WalkItem &wi, WalkItem &wo) handled = handleSetVarToFunction(var1, arg, arg1, wo); // have var1 only (var1 = UNKNOWN) if (!handled) - removeVar(wo, var1); + removeVar(wo, var1.name); } else { // have var1 and var2 (var1 = var2) - if (isIn(var2, wi.knownVars)) + if (isIn(var2.name, wi.knownVars)) { - addLinkedVar(wo, var2, var1); + addLinkedVar(wo, var2.name, var1.name); } // var2 not found in known checking pointer - else if (isNotIn(var2, wi.needCheckNullVars) && - isNotIn(var2, wi.knownVars)) + else if (isNotIn(var2.name, wi.needCheckNullVars) && + isNotIn(var2.name, wi.knownVars)) { - removeVar(wo, var1); + removeVar(wo, var1.name); } } } @@ -435,25 +436,25 @@ void analyseNeExpr(NeExprNode *node, const WalkItem &wi, WalkItem &wo) WalkItem wo2 = wo; walkTree(node2, wi, wo2); - std::string var = getVariableName(node1); + VarItem var = getVariableName(node1); // if (var != 0) if (!var.empty() && wo2.isNum && wo2.num == 0) { - if (isIn(var, wi.needCheckNullVars) || - isNotIn(var, wi.knownVars)) + if (isIn(var.name, wi.needCheckNullVars) || + isNotIn(var.name, wi.knownVars)) { - wo.checkedThenNonNullVars.insert(var); - wo.checkedElseNullVars.insert(var); - wo.knownNonNullVars.insert(var); - wo.knownVars.insert(var); + wo.checkedThenNonNullVars.insert(var.name); + wo.checkedElseNullVars.insert(var.name); + wo.knownNonNullVars.insert(var.name); + wo.knownVars.insert(var.name); wo.cleanExpr = true; wo.uselessExpr = false; return; } - else if (isIn(var, wi.knownNonNullVars) || - isIn(var, wi.knownNullVars)) + else if (isIn(var.name, wi.knownNonNullVars) || + isIn(var.name, wi.knownNullVars)) { bool doReport(true); // exception for delete operator. it check for var != 0 before really delete @@ -531,12 +532,12 @@ void analyseNeExpr(NeExprNode *node, const WalkItem &wi, WalkItem &wo) } } - wo.checkedThenNonNullVars.insert(var); - wo.checkedElseNullVars.insert(var); + wo.checkedThenNonNullVars.insert(var.name); + wo.checkedElseNullVars.insert(var.name); wo.cleanExpr = true; wo.uselessExpr = false; if (doReport) - reportUselessCheck(node, var); + reportUselessCheck(node, var.name); return; } } @@ -561,34 +562,34 @@ void analyseEqExpr(EqExprNode *node, const WalkItem &wi, WalkItem &wo) WalkItem wo2 = wo; walkTree(node2, wi, wo2); - std::string var = getVariableName(node1); + VarItem var = getVariableName(node1); // if (var == 0) if (!var.empty() && wo2.isNum && wo2.num == 0) { - if (isIn(var, wi.needCheckNullVars) || - isNotIn(var, wi.knownVars)) + if (isIn(var.name, wi.needCheckNullVars) || + isNotIn(var.name, wi.knownVars)) { - wo.checkedThenNullVars.insert(var); - wo.checkedElseNonNullVars.insert(var); - wo.knownNullVars.insert(var); - wo.knownVars.insert(var); + wo.checkedThenNullVars.insert(var.name); + wo.checkedElseNonNullVars.insert(var.name); + wo.knownNullVars.insert(var.name); + wo.knownVars.insert(var.name); wo.cleanExpr = true; wo.uselessExpr = false; - if (isIn(var, wi.knownNullVars) || - isIn(var, wi.knownNonNullVars)) + if (isIn(var.name, wi.knownNullVars) || + isIn(var.name, wi.knownNonNullVars)) { - reportUselessCheck(node, var); + reportUselessCheck(node, var.name); } return; } - else if (isIn(var, wi.knownNullVars) || - isIn(var, wi.knownNonNullVars)) + else if (isIn(var.name, wi.knownNullVars) || + isIn(var.name, wi.knownNonNullVars)) { - wo.checkedThenNullVars.insert(var); - wo.checkedElseNonNullVars.insert(var); - reportUselessCheck(node, var); + wo.checkedThenNullVars.insert(var.name); + wo.checkedElseNonNullVars.insert(var.name); + reportUselessCheck(node, var.name); wo.cleanExpr = true; wo.uselessExpr = false; return; @@ -975,7 +976,7 @@ void handleSetVarDecl(Node *node, } } -bool handleSetVarToFunctionBack(const std::string &var, +bool handleSetVarToFunctionBack(const VarItem &var, Node *node2, WalkItem &wo) { @@ -985,15 +986,15 @@ bool handleSetVarToFunctionBack(const std::string &var, if (wo2.isNum) { if (wo2.num == 0) - addNullVar(wo, var); + addNullVar(wo, var.name); else - addNonNullVar(wo, var); + addNonNullVar(wo, var.name); return true; } return false; } -bool handleSetVarToFunction(const std::string &var, +bool handleSetVarToFunction(const VarItem &var, Node *node1, Node *node2, WalkItem &wo) @@ -1009,8 +1010,8 @@ bool handleSetVarToFunction(const std::string &var, if (node2 == nullptr) { // type *var; - if (isNotIn(var, wo.knownVars)) - addUnknownVar(wo, var); + if (isNotIn(var.name, wo.knownVars)) + addUnknownVar(wo, var.name); return true; } @@ -1021,9 +1022,9 @@ bool handleSetVarToFunction(const std::string &var, { VarDeclNode *varDecl = static_cast<VarDeclNode*>(skipNop(addr->args[0])); if (skipNop(varDecl->varType) != POINTER_TYPE) - addNonNullVar(wo, var); + addNonNullVar(wo, var.name); else - addUnknownVar(wo, var); + addUnknownVar(wo, var.name); return true; } } @@ -1074,7 +1075,7 @@ bool handleSetVarToFunction(const std::string &var, return false; } FunctionDeclNode *func = static_cast<FunctionDeclNode*>(skipNop(addr->args[0])); - removeVar(wo, var); + removeVar(wo, var.name); if (func->label != "__comp_ctor ") { @@ -1098,11 +1099,11 @@ bool handleSetVarToFunction(const std::string &var, func->label == "operator new []" || func->label == "__comp_ctor ") { // function have attribute returns_nonnull. This mean result cant be null - addNonNullVar(wo, var); + addNonNullVar(wo, var.name); } else { // function not have attribute returns_nonnull. This mean result can be null - addUnknownVar(wo, var); + addUnknownVar(wo, var.name); } return true; } @@ -1113,8 +1114,8 @@ void handleSetVar(Node *node1, WalkItem &wo) { // var1 = var2 - const std::string var1 = getVariableName(node1); - const std::string var2 = getVariableName(node2); + const VarItem var1 = getVariableName(node1); + const VarItem var2 = getVariableName(node2); if (var1.empty()) return; if (var2.empty()) @@ -1125,10 +1126,10 @@ void handleSetVar(Node *node1, } else { - if (isIn(var2, wi.knownVars)) - addLinkedVar(wo, var2, var1); + if (isIn(var2.name, wi.knownVars)) + addLinkedVar(wo, var2.name, var1.name); else - addUnknownVar(wo, var1); + addUnknownVar(wo, var1.name); } } diff --git a/src/analysis/expression.h b/src/analysis/expression.h index b07f296..8d18a95 100644 --- a/src/analysis/expression.h +++ b/src/analysis/expression.h @@ -42,6 +42,7 @@ struct TruthAndExprNode; struct TruthAndIfExprNode; struct TruthOrExprNode; struct TruthOrIfExprNode; +struct VarItem; struct WalkItem; #include <vector> @@ -95,18 +96,18 @@ namespace Analysis const WalkItem &wi, WalkItem &wo); - std::string getComponentRefVariable(Node *node); + VarItem getComponentRefVariable(Node *node); - std::vector<std::string> getComponentRefParts(Node *node); + std::vector<VarItem> getComponentRefParts(Node *node); - std::vector<std::string> getComponentRefLeftParts(Node *node); + std::vector<VarItem> getComponentRefLeftParts(Node *node); - bool handleSetVarToFunction(const std::string &var, + bool handleSetVarToFunction(const VarItem &var, Node *node1, Node *node2, WalkItem &wo); - bool isValidVar(const std::string &str); + bool isValidVar(const VarItem &str); } #endif // ANALYSIS_EXPRESSION_H diff --git a/src/analysis/reports.cpp b/src/analysis/reports.cpp index 733171a..03ba641 100644 --- a/src/analysis/reports.cpp +++ b/src/analysis/reports.cpp @@ -24,6 +24,7 @@ #include "analysis/analysis.h" #include "analysis/expression.h" +#include "analysis/varitem.h" #include "analysis/walkitem.h" #include "nodes/base/node.h" @@ -95,12 +96,12 @@ void reportParmDeclNullPointer(Node *mainNode, auto vars = getComponentRefParts(node); FOR_EACH (var, vars) { - if (isIn(var, wi.needCheckNullVars) || - isNotIn(var, wi.knownVars)) + if (isIn(var.name, wi.needCheckNullVars) || + isNotIn(var.name, wi.knownVars)) { Log::warn(findBackLocation(mainNode), "Using variable '%s' without checking for null pointer", - var); + var.name); } } } @@ -120,11 +121,11 @@ void reportParmDeclLeftNullPointer(Node *mainNode, auto vars = getComponentRefLeftParts(node); FOR_EACH (var, vars) { - if (isIn(var, wi.needCheckNullVars)) + if (isIn(var.name, wi.needCheckNullVars)) { Log::warn(findBackLocation(mainNode), "Using field '%s' without checking for null pointer", - var); + var.name); } } } @@ -144,11 +145,11 @@ void reportComponentRefNullPointer(Node *mainNode, auto vars = getComponentRefParts(node); FOR_EACH (var, vars) { - if (isIn(var, wi.needCheckNullVars)) + if (isIn(var.name, wi.needCheckNullVars)) { Log::warn(findBackLocation(mainNode), "Using field '%s' without checking for null pointer", - var); + var.name); } } } @@ -185,8 +186,8 @@ void reportParmDeclAttrNullPointer(Node *mainNode, } else if (node == COMPONENT_REF) { - std::string var = getComponentRefVariable(node); - if (isIn(var, wi.needCheckNullVars)) + VarItem var = getComponentRefVariable(node); + if (isIn(var.name, wi.needCheckNullVars)) reportPossibleNullPointer(mainNode, node->label); } } diff --git a/src/analysis/varitem.h b/src/analysis/varitem.h new file mode 100644 index 0000000..1fe6b20 --- /dev/null +++ b/src/analysis/varitem.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2015 Andrei Karas + * + * This file is part of Paranoid null checker. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef ANALYSIS_VARITEM_H +#define ANALYSIS_VARITEM_H + +#include <string> + +struct VarItem +{ + VarItem() : + name() + { + } + + VarItem(const std::string &name0) : + name(name0) + { + } + + bool empty() const + { return name.empty(); } + + size_t size() const + { return name.size(); } + + std::string name; +}; + + +#endif // ANALYSIS_VARITEM_H |