Cppcheck
checkuninitvar.h
Go to the documentation of this file.
1 /*
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 #include "tokenize.h"
30 #include "vfvalue.h"
31 
32 #include <list>
33 #include <map>
34 #include <set>
35 #include <string>
36 
37 class Scope;
38 class Token;
39 class Variable;
40 class ErrorLogger;
41 class Settings;
42 class Library;
43 
44 namespace CTU {
45  class FileInfo;
46 }
47 
48 namespace tinyxml2 {
49  class XMLElement;
50 }
51 
52 
53 struct VariableValue {
54  explicit VariableValue(MathLib::bigint val = 0) : value(val) {}
56  bool notEqual{};
57 };
58 
59 /// @addtogroup Checks
60 /// @{
61 
62 
63 /** @brief Checking for uninitialized variables */
64 
66  friend class TestUninitVar;
67 
68 public:
69  /** @brief This constructor is used when registering the CheckUninitVar */
70  CheckUninitVar() : Check(myName()) {}
71 
72  enum Alloc { NO_ALLOC, NO_CTOR_CALL, CTOR_CALL, ARRAY };
73 
74  static const Token *isVariableUsage(const Token *vartok, const Library &library, bool pointer, Alloc alloc, int indirect = 0);
75  const Token *isVariableUsage(const Token *vartok, bool pointer, Alloc alloc, int indirect = 0) const;
76 
77 private:
78  /** @brief This constructor is used when running checks. */
79  CheckUninitVar(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
80  : Check(myName(), tokenizer, settings, errorLogger) {}
81 
82  /** @brief Run checks against the normal token list */
83  void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override {
84  CheckUninitVar checkUninitVar(&tokenizer, &tokenizer.getSettings(), errorLogger);
85  checkUninitVar.valueFlowUninit();
86  checkUninitVar.check();
87  }
88 
89  bool diag(const Token* tok);
90  /** Check for uninitialized variables */
91  void check();
92  void checkScope(const Scope* scope, const std::set<std::string> &arrayTypeDefs);
93  void checkStruct(const Token *tok, const Variable &structvar);
94  bool checkScopeForVariable(const Token *tok, const Variable& var, bool* const possibleInit, bool* const noreturn, Alloc* const alloc, const std::string &membervar, std::map<nonneg int, VariableValue>& variableValue);
95  const Token* checkExpr(const Token* tok, const Variable& var, const Alloc alloc, bool known, bool* bailout = nullptr) const;
96  bool checkIfForWhileHead(const Token *startparentheses, const Variable& var, bool suppressErrors, bool isuninit, Alloc alloc, const std::string &membervar);
97  bool checkLoopBody(const Token *tok, const Variable& var, const Alloc alloc, const std::string &membervar, const bool suppressErrors);
98  const Token* checkLoopBodyRecursive(const Token *start, const Variable& var, const Alloc alloc, const std::string &membervar, bool &bailout) const;
99  void checkRhs(const Token *tok, const Variable &var, Alloc alloc, nonneg int number_of_if, const std::string &membervar);
100  static int isFunctionParUsage(const Token *vartok, const Library &library, bool pointer, Alloc alloc, int indirect = 0);
101  int isFunctionParUsage(const Token *vartok, bool pointer, Alloc alloc, int indirect = 0) const;
102  bool isMemberVariableAssignment(const Token *tok, const std::string &membervar) const;
103  bool isMemberVariableUsage(const Token *tok, bool isPointer, Alloc alloc, const std::string &membervar) const;
104 
105  /** ValueFlow-based checking for uninitialized variables */
106  void valueFlowUninit();
107 
108  /** @brief Parse current TU and extract file info */
109  Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings &settings) const override;
110 
111  Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const override;
112 
113  /** @brief Analyse all file infos for all TU */
114  bool analyseWholeProgram(const CTU::FileInfo *ctu, const std::list<Check::FileInfo*> &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override;
115 
116  void uninitvarError(const Token* tok, const ValueFlow::Value& v);
117  void uninitdataError(const Token *tok, const std::string &varname);
118  void uninitvarError(const Token *tok, const std::string &varname, ErrorPath errorPath);
119  void uninitvarError(const Token *tok, const std::string &varname) {
120  uninitvarError(tok, varname, ErrorPath{});
121  }
122  void uninitvarError(const Token *tok, const std::string &varname, Alloc alloc) {
123  if (alloc == NO_CTOR_CALL || alloc == CTOR_CALL)
124  uninitdataError(tok, varname);
125  else
126  uninitvarError(tok, varname);
127  }
128  void uninitStructMemberError(const Token *tok, const std::string &membername);
129 
130  std::set<const Token*> mUninitDiags;
131 
132  void getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const override
133  {
134  CheckUninitVar c(nullptr, settings, errorLogger);
135 
136  ValueFlow::Value v{};
137 
138  c.uninitvarError(nullptr, v);
139  c.uninitdataError(nullptr, "varname");
140  c.uninitStructMemberError(nullptr, "a.b");
141  }
142 
143  static std::string myName() {
144  return "Uninitialized variables";
145  }
146 
147  std::string classInfo() const override {
148  return "Uninitialized variables\n"
149  "- using uninitialized local variables\n"
150  "- using allocated data before it has been initialized\n";
151  }
152 };
153 /// @}
154 //---------------------------------------------------------------------------
155 #endif // checkuninitvarH
static bool isVariableUsage(const Settings &settings, const Token *vartok, MathLib::bigint *value)
Checking for uninitialized variables.
std::string classInfo() const override
get information about this class, used to generate documentation
void valueFlowUninit()
ValueFlow-based checking for uninitialized variables.
static std::string myName()
void check()
Check for uninitialized variables.
void uninitvarError(const Token *tok, const std::string &varname, Alloc alloc)
void uninitvarError(const Token *tok, const std::string &varname)
void uninitdataError(const Token *tok, const std::string &varname)
CheckUninitVar()
This constructor is used when registering the CheckUninitVar.
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override
get error messages
void uninitStructMemberError(const Token *tok, const std::string &membername)
std::set< const Token * > mUninitDiags
void uninitvarError(const Token *tok, const ValueFlow::Value &v)
CheckUninitVar(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
This constructor is used when running checks.
void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override
Run checks against the normal token list.
Base class used for whole-program analysis.
Definition: check.h:103
Interface class that cppcheck uses to communicate with the checks.
Definition: check.h:59
virtual bool analyseWholeProgram(const CTU::FileInfo *ctu, const std::list< FileInfo * > &fileInfo, const Settings &, ErrorLogger &)
Definition: check.h:122
virtual FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const
Definition: check.h:116
virtual FileInfo * getFileInfo(const Tokenizer &, const Settings &) const
Definition: check.h:112
This is an interface, which the class responsible of error logging should implement.
Definition: errorlogger.h:214
Library definitions handling.
Definition: library.h:52
long long bigint
Definition: mathlib.h:68
This is just a container for general settings so that we don't need to pass individual values to func...
Definition: settings.h:95
The token list that the TokenList generates is a linked-list of this class.
Definition: token.h:150
The main purpose is to tokenize the source code.
Definition: tokenize.h:46
const Settings & getSettings() const
Definition: tokenize.h:615
Information about a member variable.
#define CPPCHECKLIB
Definition: config.h:35
#define nonneg
Definition: config.h:138
std::list< ErrorPathItem > ErrorPath
Definition: errortypes.h:130
Whole program analysis (ctu=Cross Translation Unit)
Definition: check.h:35
Definition: check.h:31
MathLib::bigint value
VariableValue(MathLib::bigint val=0)
static void valueFlowUninit(TokenList &tokenlist, ErrorLogger &errorLogger, const Settings &settings)
Definition: valueflow.cpp:8116
#define bailout(tokenlist, errorLogger, tok, what)
Definition: valueflow.cpp:144