/src/cppcheck/lib/checkuninitvar.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- C++ -*- |
2 | | * Cppcheck - A tool for static C/C++ code analysis |
3 | | * Copyright (C) 2007-2024 Cppcheck team. |
4 | | * |
5 | | * This program is free software: you can redistribute it and/or modify |
6 | | * it under the terms of the GNU General Public License as published by |
7 | | * the Free Software Foundation, either version 3 of the License, or |
8 | | * (at your option) any later version. |
9 | | * |
10 | | * This program is distributed in the hope that it will be useful, |
11 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | | * GNU General Public License for more details. |
14 | | * |
15 | | * You should have received a copy of the GNU General Public License |
16 | | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | | */ |
18 | | |
19 | | |
20 | | //--------------------------------------------------------------------------- |
21 | | #ifndef checkuninitvarH |
22 | | #define checkuninitvarH |
23 | | //--------------------------------------------------------------------------- |
24 | | |
25 | | #include "check.h" |
26 | | #include "config.h" |
27 | | #include "mathlib.h" |
28 | | #include "errortypes.h" |
29 | | |
30 | | #include <cstdint> |
31 | | #include <map> |
32 | | #include <set> |
33 | | #include <string> |
34 | | |
35 | | class Scope; |
36 | | class Token; |
37 | | class Variable; |
38 | | class ErrorLogger; |
39 | | class Settings; |
40 | | class Library; |
41 | | class Tokenizer; |
42 | | namespace ValueFlow |
43 | | { |
44 | | class Value; |
45 | | } |
46 | | |
47 | | struct VariableValue { |
48 | 0 | explicit VariableValue(MathLib::bigint val = 0) : value(val) {} |
49 | | MathLib::bigint value; |
50 | | bool notEqual{}; |
51 | | }; |
52 | | |
53 | | /// @addtogroup Checks |
54 | | /// @{ |
55 | | |
56 | | |
57 | | /** @brief Checking for uninitialized variables */ |
58 | | |
59 | | class CPPCHECKLIB CheckUninitVar : public Check { |
60 | | friend class TestUninitVar; |
61 | | |
62 | | public: |
63 | | /** @brief This constructor is used when registering the CheckUninitVar */ |
64 | 2 | CheckUninitVar() : Check(myName()) {} |
65 | | |
66 | | enum Alloc : std::uint8_t { NO_ALLOC, NO_CTOR_CALL, CTOR_CALL, ARRAY }; |
67 | | |
68 | | static const Token *isVariableUsage(const Token *vartok, const Library &library, bool pointer, Alloc alloc, int indirect = 0); |
69 | | const Token *isVariableUsage(const Token *vartok, bool pointer, Alloc alloc, int indirect = 0) const; |
70 | | |
71 | | private: |
72 | | /** @brief This constructor is used when running checks. */ |
73 | | CheckUninitVar(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) |
74 | 763 | : Check(myName(), tokenizer, settings, errorLogger) {} |
75 | | |
76 | | /** @brief Run checks against the normal token list */ |
77 | | void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; |
78 | | |
79 | | bool diag(const Token* tok); |
80 | | /** Check for uninitialized variables */ |
81 | | void check(); |
82 | | void checkScope(const Scope* scope, const std::set<std::string> &arrayTypeDefs); |
83 | | void checkStruct(const Token *tok, const Variable &structvar); |
84 | | bool checkScopeForVariable(const Token *tok, const Variable& var, bool* possibleInit, bool* noreturn, Alloc* alloc, const std::string &membervar, std::map<nonneg int, VariableValue>& variableValue); |
85 | | const Token* checkExpr(const Token* tok, const Variable& var, Alloc alloc, bool known, bool* bailout = nullptr) const; |
86 | | bool checkIfForWhileHead(const Token *startparentheses, const Variable& var, bool suppressErrors, bool isuninit, Alloc alloc, const std::string &membervar); |
87 | | bool checkLoopBody(const Token *tok, const Variable& var, Alloc alloc, const std::string &membervar, bool suppressErrors); |
88 | | const Token* checkLoopBodyRecursive(const Token *start, const Variable& var, Alloc alloc, const std::string &membervar, bool &bailout, bool &alwaysReturns) const; |
89 | | void checkRhs(const Token *tok, const Variable &var, Alloc alloc, nonneg int number_of_if, const std::string &membervar); |
90 | | static int isFunctionParUsage(const Token *vartok, const Library &library, bool pointer, Alloc alloc, int indirect = 0); |
91 | | int isFunctionParUsage(const Token *vartok, bool pointer, Alloc alloc, int indirect = 0) const; |
92 | | bool isMemberVariableAssignment(const Token *tok, const std::string &membervar) const; |
93 | | bool isMemberVariableUsage(const Token *tok, bool isPointer, Alloc alloc, const std::string &membervar) const; |
94 | | |
95 | | /** ValueFlow-based checking for uninitialized variables */ |
96 | | void valueFlowUninit(); |
97 | | |
98 | | /** @brief Parse current TU and extract file info */ |
99 | | Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings &settings) const override; |
100 | | |
101 | | Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const override; |
102 | | |
103 | | /** @brief Analyse all file infos for all TU */ |
104 | | bool analyseWholeProgram(const CTU::FileInfo &ctu, const std::list<Check::FileInfo*> &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; |
105 | | |
106 | | void uninitvarError(const Token* tok, const ValueFlow::Value& v); |
107 | | void uninitdataError(const Token *tok, const std::string &varname); |
108 | | void uninitvarError(const Token *tok, const std::string &varname, ErrorPath errorPath); |
109 | 0 | void uninitvarError(const Token *tok, const std::string &varname) { |
110 | 0 | uninitvarError(tok, varname, ErrorPath{}); |
111 | 0 | } |
112 | 0 | void uninitvarError(const Token *tok, const std::string &varname, Alloc alloc) { |
113 | 0 | if (alloc == NO_CTOR_CALL || alloc == CTOR_CALL) |
114 | 0 | uninitdataError(tok, varname); |
115 | 0 | else |
116 | 0 | uninitvarError(tok, varname); |
117 | 0 | } |
118 | | void uninitStructMemberError(const Token *tok, const std::string &membername); |
119 | | |
120 | | std::set<const Token*> mUninitDiags; |
121 | | |
122 | | void getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const override; |
123 | | |
124 | 765 | static std::string myName() { |
125 | 765 | return "Uninitialized variables"; |
126 | 765 | } |
127 | | |
128 | 0 | std::string classInfo() const override { |
129 | 0 | return "Uninitialized variables\n" |
130 | 0 | "- using uninitialized local variables\n" |
131 | 0 | "- using allocated data before it has been initialized\n"; |
132 | 0 | } |
133 | | }; |
134 | | /// @} |
135 | | //--------------------------------------------------------------------------- |
136 | | #endif // checkuninitvarH |