From fc1658509ff1e1b5c967f0805a6d6e0e1b197a06 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sat, 27 Jun 2015 21:07:04 +0300 Subject: Check function parameters what must be non null and report if variable must be checked for null --- src/analysis/analysis.cpp | 37 +++++++++++++++++++++++++++++++++++++ src/analysis/analysis.h | 4 ++++ src/analysis/expression.cpp | 16 ++++++++++++++++ src/analysis/function.h | 5 +++++ 4 files changed, 62 insertions(+) (limited to 'src') diff --git a/src/analysis/analysis.cpp b/src/analysis/analysis.cpp index b246eba..490bb66 100644 --- a/src/analysis/analysis.cpp +++ b/src/analysis/analysis.cpp @@ -257,6 +257,43 @@ void reportParmDeclNullPointer(Node *mainNode, } } +void reportPossibleNullPointer(Node *node, + const std::string &label) +{ + Log::warn(findBackLocation(node), + "warning: possible null argument '%s' where non-null required", + label); +} + +void reportParmDeclAttrNullPointer(Node *mainNode, + Node *node, + const WalkItem &wi) +{ + node = skipNop(node); + if (node) + { + if (!node->label.empty()) + { + if (node == PARM_DECL) + { + if (wi.checkNullVars.find(node->label) != wi.checkNullVars.end()) + reportPossibleNullPointer(mainNode, node->label); + } + else if (node == VAR_DECL) + { + if (wi.checkNullVars.find(node->label) != wi.checkNullVars.end()) + reportPossibleNullPointer(mainNode, node->label); + } + } + else if (node == COMPONENT_REF) + { + std::string var = getComponentRefVariable(node); + if (wi.checkNullVars.find(var) != wi.checkNullVars.end()) + reportPossibleNullPointer(mainNode, node->label); + } + } +} + // skip all child nodes and return non nop child Node *skipNop(Node *node) { diff --git a/src/analysis/analysis.h b/src/analysis/analysis.h index cc0763d..b371ab3 100644 --- a/src/analysis/analysis.h +++ b/src/analysis/analysis.h @@ -42,6 +42,10 @@ namespace Analysis Node *node, const WalkItem &wi); + void reportParmDeclAttrNullPointer(Node *mainNode, + Node *node, + const WalkItem &wi); + bool checkForReport(Node *node, const WalkItem &wi); diff --git a/src/analysis/expression.cpp b/src/analysis/expression.cpp index 1711de2..c607e9e 100644 --- a/src/analysis/expression.cpp +++ b/src/analysis/expression.cpp @@ -23,6 +23,7 @@ #include "logger.h" #include "analysis/analysis.h" +#include "analysis/function.h" #include "analysis/statement.h" #include "analysis/walkitem.h" @@ -457,6 +458,7 @@ void analyseCallExpr(CallExprNode *node, const WalkItem &wi, WalkItem &wo) Log::dumpWI(node, "wo chain ", wo2); wo2 = wo; bool enableCheck(true); + std::set nullAttrs; if (node->function) { walkTree(node->function, wi, wo2); @@ -470,6 +472,7 @@ void analyseCallExpr(CallExprNode *node, const WalkItem &wi, WalkItem &wo) Node *decl = skipNop(addrNode->args[0]); if (decl == FUNCTION_DECL) { + function = decl; FunctionDeclNode *declNode = static_cast( decl); if (declNode->functionType == FUNCTION_TYPE) @@ -504,7 +507,14 @@ void analyseCallExpr(CallExprNode *node, const WalkItem &wi, WalkItem &wo) if (!getVariableName(function).empty()) enableCheck = false; } + if (function == FUNCTION_DECL) + { + getFunctionParamsNonNullAttributes( + static_cast(function), + nullAttrs); + } } + int param = 1; FOR_EACH (std::vector::const_iterator, it, node->args) { wo2 = wo; @@ -514,8 +524,14 @@ void analyseCallExpr(CallExprNode *node, const WalkItem &wi, WalkItem &wo) reportParmDeclNullPointer(node, node2, wi); enableCheck = false; } + else + { + if (nullAttrs.find(param) != nullAttrs.end()) + reportParmDeclAttrNullPointer(node, node2, wi); + } walkTree(node2, wi, wo2); Log::dumpWI(node, "wo arg ", wo2); + param ++; } wo.stopWalking = true; } diff --git a/src/analysis/function.h b/src/analysis/function.h index ad85bfa..f7e0a66 100644 --- a/src/analysis/function.h +++ b/src/analysis/function.h @@ -22,6 +22,8 @@ #include "includes.h" +#include + struct FunctionDeclNode; struct TreeListNode; struct TypeNode; @@ -33,6 +35,9 @@ namespace Analysis void getFunctionArgTypes(FunctionDeclNode *node, std::vector &arr); + + void getFunctionParamsNonNullAttributes(FunctionDeclNode *node, + std::set &arr); } #endif // ANALYSIS_FUNCTION_H -- cgit v1.2.3-60-g2f50