Cppcheck
checkfunctions.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 checkfunctionsH
22 #define checkfunctionsH
23 //---------------------------------------------------------------------------
24 
25 #include "check.h"
26 #include "config.h"
27 #include "errortypes.h"
28 #include "library.h"
29 #include "settings.h"
30 #include "tokenize.h"
31 
32 #include <map>
33 #include <string>
34 
35 class Token;
36 class ErrorLogger;
37 
38 namespace ValueFlow {
39  class Value;
40 } // namespace ValueFlow
41 
42 
43 /// @addtogroup Checks
44 /// @{
45 
46 /**
47  * @brief Check for bad function usage
48  */
49 
51 public:
52  /** This constructor is used when registering the CheckFunctions */
53  CheckFunctions() : Check(myName()) {}
54 
55 private:
56  /** This constructor is used when running checks. */
57  CheckFunctions(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
58  : Check(myName(), tokenizer, settings, errorLogger) {}
59 
60  /** @brief Run checks against the normal token list */
61  void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override {
62  CheckFunctions checkFunctions(&tokenizer, &tokenizer.getSettings(), errorLogger);
63 
64  checkFunctions.checkIgnoredReturnValue();
65  checkFunctions.checkMissingReturn(); // Missing "return" in exit path
66 
67  // --check-library : functions with nonmatching configuration
68  checkFunctions.checkLibraryMatchFunctions();
69 
70  checkFunctions.checkProhibitedFunctions();
71  checkFunctions.invalidFunctionUsage();
72  checkFunctions.checkMathFunctions();
73  checkFunctions.memsetZeroBytes();
74  checkFunctions.memsetInvalid2ndParam();
75  checkFunctions.returnLocalStdMove();
76  checkFunctions.useStandardLibrary();
77  }
78 
79  /** Check for functions that should not be used */
80  void checkProhibitedFunctions();
81 
82  /**
83  * @brief Invalid function usage (invalid input value / overlapping data)
84  *
85  * %Check that given function parameters are valid according to the standard
86  * - wrong radix given for strtol/strtoul
87  * - overlapping data when using sprintf/snprintf
88  * - wrong input value according to library
89  */
90  void invalidFunctionUsage();
91 
92  /** @brief %Check for ignored return values. */
93  void checkIgnoredReturnValue();
94 
95  /** @brief %Check for parameters given to math function that do not make sense*/
96  void checkMathFunctions();
97 
98  /** @brief %Check for filling zero bytes with memset() */
99  void memsetZeroBytes();
100 
101  /** @brief %Check for invalid 2nd parameter of memset() */
102  void memsetInvalid2ndParam();
103 
104  /** @brief %Check for copy elision by RVO|NRVO */
105  void returnLocalStdMove();
106 
107  void useStandardLibrary();
108 
109  /** @brief --check-library: warn for unconfigured function calls */
110  void checkLibraryMatchFunctions();
111 
112  /** @brief %Check for missing "return" */
113  void checkMissingReturn();
114 
115  void invalidFunctionArgError(const Token *tok, const std::string &functionName, int argnr, const ValueFlow::Value *invalidValue, const std::string &validstr);
116  void invalidFunctionArgBoolError(const Token *tok, const std::string &functionName, int argnr);
117  void invalidFunctionArgStrError(const Token *tok, const std::string &functionName, nonneg int argnr);
118  void ignoredReturnValueError(const Token* tok, const std::string& function);
119  void ignoredReturnErrorCode(const Token* tok, const std::string& function);
120  void mathfunctionCallWarning(const Token *tok, const nonneg int numParam = 1);
121  void mathfunctionCallWarning(const Token *tok, const std::string& oldexp, const std::string& newexp);
122  void memsetZeroBytesError(const Token *tok);
123  void memsetFloatError(const Token *tok, const std::string &var_value);
124  void memsetValueOutOfRangeError(const Token *tok, const std::string &value);
125  void missingReturnError(const Token *tok);
126  void copyElisionError(const Token *tok);
127  void useStandardLibraryError(const Token *tok, const std::string& expected);
128 
129  void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override {
130  CheckFunctions c(nullptr, settings, errorLogger);
131 
132  for (std::map<std::string, Library::WarnInfo>::const_iterator i = settings->library.functionwarn.cbegin(); i != settings->library.functionwarn.cend(); ++i) {
133  c.reportError(nullptr, Severity::style, i->first+"Called", i->second.message);
134  }
135 
136  c.invalidFunctionArgError(nullptr, "func_name", 1, nullptr,"1:4");
137  c.invalidFunctionArgBoolError(nullptr, "func_name", 1);
138  c.invalidFunctionArgStrError(nullptr, "func_name", 1);
139  c.ignoredReturnValueError(nullptr, "malloc");
140  c.mathfunctionCallWarning(nullptr);
141  c.mathfunctionCallWarning(nullptr, "1 - erf(x)", "erfc(x)");
142  c.memsetZeroBytesError(nullptr);
143  c.memsetFloatError(nullptr, "varname");
144  c.memsetValueOutOfRangeError(nullptr, "varname");
145  c.missingReturnError(nullptr);
146  c.copyElisionError(nullptr);
147  c.useStandardLibraryError(nullptr, "memcpy");
148  }
149 
150  static std::string myName() {
151  return "Check function usage";
152  }
153 
154  std::string classInfo() const override {
155  return "Check function usage:\n"
156  "- missing 'return' in non-void function\n"
157  "- return value of certain functions not used\n"
158  "- invalid input values for functions\n"
159  "- Warn if a function is called whose usage is discouraged\n"
160  "- memset() third argument is zero\n"
161  "- memset() with a value out of range as the 2nd parameter\n"
162  "- memset() with a float as the 2nd parameter\n"
163  "- copy elision optimization for returning value affected by std::move\n"
164  "- use memcpy()/memset() instead of for loop\n";
165  }
166 };
167 /// @}
168 //---------------------------------------------------------------------------
169 #endif // checkfunctionsH
Check for bad function usage.
void checkMissingReturn()
Check for missing "return"
void checkProhibitedFunctions()
Check for functions that should not be used.
void memsetZeroBytes()
Check for filling zero bytes with memset()
void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override
Run checks against the normal token list.
void ignoredReturnValueError(const Token *tok, const std::string &function)
void invalidFunctionArgError(const Token *tok, const std::string &functionName, int argnr, const ValueFlow::Value *invalidValue, const std::string &validstr)
void memsetZeroBytesError(const Token *tok)
void invalidFunctionArgStrError(const Token *tok, const std::string &functionName, nonneg int argnr)
void checkIgnoredReturnValue()
Check for ignored return values.
void missingReturnError(const Token *tok)
CheckFunctions()
This constructor is used when registering the CheckFunctions.
void memsetValueOutOfRangeError(const Token *tok, const std::string &value)
void invalidFunctionUsage()
Invalid function usage (invalid input value / overlapping data)
void checkLibraryMatchFunctions()
–check-library: warn for unconfigured function calls
void mathfunctionCallWarning(const Token *tok, const nonneg int numParam=1)
void invalidFunctionArgBoolError(const Token *tok, const std::string &functionName, int argnr)
void useStandardLibraryError(const Token *tok, const std::string &expected)
void memsetInvalid2ndParam()
Check for invalid 2nd parameter of memset()
static std::string myName()
void checkMathFunctions()
Check for parameters given to math function that do not make sense
std::string classInfo() const override
get information about this class, used to generate documentation
void copyElisionError(const Token *tok)
void returnLocalStdMove()
Check for copy elision by RVO|NRVO
CheckFunctions(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
This constructor is used when running checks.
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override
get error messages
void memsetFloatError(const Token *tok, const std::string &var_value)
Interface class that cppcheck uses to communicate with the checks.
Definition: check.h:59
void reportError(const Token *tok, const Severity severity, const std::string &id, const std::string &msg)
report an error
Definition: check.h:138
This is an interface, which the class responsible of error logging should implement.
Definition: errorlogger.h:214
std::map< std::string, WarnInfo > functionwarn
Definition: library.h:174
This is just a container for general settings so that we don't need to pass individual values to func...
Definition: settings.h:95
Library library
Library.
Definition: settings.h:237
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
#define CPPCHECKLIB
Definition: config.h:35
#define nonneg
Definition: config.h:138
@ style
Style warning.