2011-07-28 23:29:16 +02:00
|
|
|
/*
|
|
|
|
* Cppcheck - A tool for static C/C++ code analysis
|
2016-01-01 14:34:45 +01:00
|
|
|
* Copyright (C) 2007-2016 Cppcheck team.
|
2011-07-28 23:29:16 +02:00
|
|
|
*
|
|
|
|
* 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
|
|
|
|
* (at your option) 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/>.
|
|
|
|
*/
|
|
|
|
|
2015-11-21 20:24:30 +01:00
|
|
|
|
2011-07-28 23:29:16 +02:00
|
|
|
//---------------------------------------------------------------------------
|
2015-11-21 20:24:30 +01:00
|
|
|
#ifndef checkfunctionsH
|
|
|
|
#define checkfunctionsH
|
2011-07-28 23:29:16 +02:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#include "check.h"
|
2017-05-27 04:33:47 +02:00
|
|
|
#include "config.h"
|
|
|
|
#include "errorlogger.h"
|
|
|
|
#include "library.h"
|
|
|
|
#include "settings.h"
|
|
|
|
|
|
|
|
#include <map>
|
2011-07-28 23:29:16 +02:00
|
|
|
#include <string>
|
2017-05-27 04:33:47 +02:00
|
|
|
#include <utility>
|
|
|
|
|
|
|
|
class Token;
|
|
|
|
class Tokenizer;
|
|
|
|
namespace ValueFlow {
|
2017-05-28 15:56:26 +02:00
|
|
|
class Value;
|
2017-05-27 04:33:47 +02:00
|
|
|
} // namespace ValueFlow
|
2011-07-28 23:29:16 +02:00
|
|
|
|
|
|
|
|
|
|
|
/// @addtogroup Checks
|
|
|
|
/// @{
|
|
|
|
|
|
|
|
/**
|
2015-11-22 13:48:55 +01:00
|
|
|
* @brief Check for bad function usage
|
2011-07-28 23:29:16 +02:00
|
|
|
*/
|
|
|
|
|
2015-11-21 20:24:30 +01:00
|
|
|
class CPPCHECKLIB CheckFunctions : public Check {
|
2011-07-28 23:29:16 +02:00
|
|
|
public:
|
2015-11-21 20:24:30 +01:00
|
|
|
/** This constructor is used when registering the CheckFunctions */
|
|
|
|
CheckFunctions() : Check(myName()) {
|
2011-07-28 23:29:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/** This constructor is used when running checks. */
|
2015-11-21 20:24:30 +01:00
|
|
|
CheckFunctions(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
2014-11-20 14:20:09 +01:00
|
|
|
: Check(myName(), tokenizer, settings, errorLogger) {
|
2011-07-28 23:29:16 +02:00
|
|
|
}
|
|
|
|
|
2015-11-22 13:48:55 +01:00
|
|
|
/** @brief Run checks against the normal token list */
|
|
|
|
void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) {
|
|
|
|
CheckFunctions checkFunctions(tokenizer, settings, errorLogger);
|
|
|
|
|
|
|
|
// Checks
|
|
|
|
checkFunctions.checkIgnoredReturnValue();
|
|
|
|
|
|
|
|
// --check-library : functions with nonmatching configuration
|
|
|
|
checkFunctions.checkLibraryMatchFunctions();
|
|
|
|
}
|
|
|
|
|
|
|
|
/** @brief Run checks against the simplified token list */
|
2014-11-20 14:20:09 +01:00
|
|
|
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) {
|
2015-11-21 20:24:30 +01:00
|
|
|
CheckFunctions checkFunctions(tokenizer, settings, errorLogger);
|
2015-11-22 13:48:55 +01:00
|
|
|
|
|
|
|
checkFunctions.checkProhibitedFunctions();
|
|
|
|
checkFunctions.invalidFunctionUsage();
|
|
|
|
checkFunctions.checkMathFunctions();
|
2017-04-23 07:53:41 +02:00
|
|
|
checkFunctions.memsetZeroBytes();
|
|
|
|
checkFunctions.memsetInvalid2ndParam();
|
2011-07-28 23:29:16 +02:00
|
|
|
}
|
|
|
|
|
2015-11-21 20:24:30 +01:00
|
|
|
/** Check for functions that should not be used */
|
2015-11-22 13:48:55 +01:00
|
|
|
void checkProhibitedFunctions();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Invalid function usage (invalid input value / overlapping data)
|
|
|
|
*
|
|
|
|
* %Check that given function parameters are valid according to the standard
|
|
|
|
* - wrong radix given for strtol/strtoul
|
|
|
|
* - overlapping data when using sprintf/snprintf
|
|
|
|
* - wrong input value according to library
|
|
|
|
*/
|
|
|
|
void invalidFunctionUsage();
|
|
|
|
|
|
|
|
/** @brief %Check for ignored return values. */
|
|
|
|
void checkIgnoredReturnValue();
|
|
|
|
|
|
|
|
/** @brief %Check for parameters given to math function that do not make sense*/
|
|
|
|
void checkMathFunctions();
|
|
|
|
|
2017-04-23 07:53:41 +02:00
|
|
|
/** @brief %Check for filling zero bytes with memset() */
|
|
|
|
void memsetZeroBytes();
|
|
|
|
|
|
|
|
/** @brief %Check for invalid 2nd parameter of memset() */
|
|
|
|
void memsetInvalid2ndParam();
|
|
|
|
|
2015-11-22 13:48:55 +01:00
|
|
|
/** @brief --check-library: warn for unconfigured function calls */
|
|
|
|
void checkLibraryMatchFunctions();
|
2011-07-28 23:29:16 +02:00
|
|
|
|
|
|
|
private:
|
2017-04-20 22:14:54 +02:00
|
|
|
void invalidFunctionArgError(const Token *tok, const std::string &functionName, int argnr, const ValueFlow::Value *invalidValue, const std::string &validstr);
|
2015-11-22 13:48:55 +01:00
|
|
|
void invalidFunctionArgBoolError(const Token *tok, const std::string &functionName, int argnr);
|
|
|
|
void ignoredReturnValueError(const Token* tok, const std::string& function);
|
|
|
|
void mathfunctionCallWarning(const Token *tok, const unsigned int numParam = 1);
|
|
|
|
void mathfunctionCallWarning(const Token *tok, const std::string& oldexp, const std::string& newexp);
|
2017-04-23 07:53:41 +02:00
|
|
|
void memsetZeroBytesError(const Token *tok);
|
|
|
|
void memsetFloatError(const Token *tok, const std::string &var_value);
|
|
|
|
void memsetValueOutOfRangeError(const Token *tok, const std::string &value);
|
2015-11-22 13:48:55 +01:00
|
|
|
|
2015-11-21 20:24:30 +01:00
|
|
|
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const {
|
2016-05-07 16:30:54 +02:00
|
|
|
CheckFunctions c(nullptr, settings, errorLogger);
|
2011-07-28 23:29:16 +02:00
|
|
|
|
2015-11-21 20:24:30 +01:00
|
|
|
for (std::map<std::string, Library::WarnInfo>::const_iterator i = settings->library.functionwarn.cbegin(); i != settings->library.functionwarn.cend(); ++i) {
|
2016-05-07 16:30:54 +02:00
|
|
|
c.reportError(nullptr, Severity::style, i->first+"Called", i->second.message);
|
2015-11-21 20:24:30 +01:00
|
|
|
}
|
2015-11-22 13:48:55 +01:00
|
|
|
|
2017-04-20 22:14:54 +02:00
|
|
|
c.invalidFunctionArgError(nullptr, "func_name", 1, nullptr,"1:4");
|
2016-05-07 16:30:54 +02:00
|
|
|
c.invalidFunctionArgBoolError(nullptr, "func_name", 1);
|
|
|
|
c.ignoredReturnValueError(nullptr, "malloc");
|
|
|
|
c.mathfunctionCallWarning(nullptr);
|
|
|
|
c.mathfunctionCallWarning(nullptr, "1 - erf(x)", "erfc(x)");
|
2017-04-23 07:53:41 +02:00
|
|
|
c.memsetZeroBytesError(nullptr);
|
|
|
|
c.memsetFloatError(nullptr, "varname");
|
|
|
|
c.memsetValueOutOfRangeError(nullptr, "varname");
|
2015-11-21 20:24:30 +01:00
|
|
|
}
|
2011-07-28 23:29:16 +02:00
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
static std::string myName() {
|
2015-11-21 20:24:30 +01:00
|
|
|
return "Check function usage";
|
2011-07-28 23:29:16 +02:00
|
|
|
}
|
|
|
|
|
2015-11-21 20:24:30 +01:00
|
|
|
std::string classInfo() const {
|
2015-11-22 13:48:55 +01:00
|
|
|
return "Check function usage:\n"
|
|
|
|
"- return value of certain functions not used\n"
|
|
|
|
"- invalid input values for functions\n"
|
2017-04-23 07:53:41 +02:00
|
|
|
"- Warn if a function is called whose usage is discouraged\n"
|
|
|
|
"- memset() third argument is zero\n"
|
|
|
|
"- memset() with a value out of range as the 2nd parameter\n"
|
|
|
|
"- memset() with a float as the 2nd parameter\n";
|
2015-11-21 20:24:30 +01:00
|
|
|
}
|
2011-07-28 23:29:16 +02:00
|
|
|
};
|
|
|
|
/// @}
|
|
|
|
//---------------------------------------------------------------------------
|
2015-11-21 20:24:30 +01:00
|
|
|
#endif // checkfunctionsH
|