Skip to content

Commit

Permalink
Replaced CheckNonReentrantFunctions and CheckObsoleteFunctions by gen…
Browse files Browse the repository at this point in the history
…eric CheckFunctions which is based on Library (#6529)
  • Loading branch information
PKEuS committed Nov 22, 2015
1 parent 517922f commit 57d1196
Show file tree
Hide file tree
Showing 18 changed files with 956 additions and 547 deletions.
600 changes: 592 additions & 8 deletions cfg/posix.cfg

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion cfg/std.cfg
Expand Up @@ -92,6 +92,7 @@
<not-null/>
<not-uninit/>
</arg>
<warn severity="style" cstd="c99" alternatives="strftime" reason="Obsolete"/>
</function>
<!-- void assert(int expression) -->
<function name="assert">
Expand Down Expand Up @@ -1435,12 +1436,14 @@
</arg>
</function>
<!-- char *gets(char *buffer); -->
<function name="gets">
<function name="gets,std::gets">
<noreturn>false</noreturn>
<leak-ignore/>
<arg nr="1">
<not-null/>
</arg>
<warn severity="warning">Obsolete function 'gets' called. It is recommended to use 'fgets' instead.
The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun if the input data exceeds the size of the buffer. It is recommended to use the function 'fgets' instead.</warn>
</function>
<!-- struct tm * gmtime(const time_t *tp); -->
<function name="gmtime,std::gmtime">
Expand Down
71 changes: 71 additions & 0 deletions lib/checkfunctions.cpp
@@ -0,0 +1,71 @@
/*
* Cppcheck - A tool for static C/C++ code analysis
* Copyright (C) 2007-2015 Cppcheck team.
*
* 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/>.
*/

//---------------------------------------------------------------------------
// Check functions
//---------------------------------------------------------------------------

#include "checkfunctions.h"
#include "symboldatabase.h"

//---------------------------------------------------------------------------


// Register this check class (by creating a static instance of it)
namespace {
CheckFunctions instance;
}

void CheckFunctions::check()
{
const bool checkAlloca = (_settings->standards.c >= Standards::C99 && _tokenizer->isC()) || _settings->standards.cpp >= Standards::CPP11;

const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
for (unsigned int i = 0; i < symbolDatabase->functionScopes.size(); i++) {
const Scope* scope = symbolDatabase->functionScopes[i];
for (const Token* tok = scope->classStart; tok != scope->classEnd; tok = tok->next()) {
if (tok->isName() && tok->varId() == 0 && tok->strAt(1) == "(") {
// alloca() is special as it depends on the code being C or C++, so it is not in Library
if (checkAlloca && Token::Match(tok, "alloca (") && (!tok->function() || tok->function()->nestedIn->type == Scope::eGlobal)) {
if (_tokenizer->isC())
reportError(tok, Severity::warning, "allocaCalled",
"Obsolete function 'alloca' called. In C99 and later it is recommended to use a variable length array instead.\n"
"The obsolete function 'alloca' is called. In C99 and later it is recommended to use a variable length array or "
"a dynamically allocated array instead. The function 'alloca' is dangerous for many reasons "
"(http://stackoverflow.com/questions/1018853/why-is-alloca-not-considered-good-practice and http://linux.die.net/man/3/alloca).");
else
reportError(tok, Severity::warning, "allocaCalled",
"Obsolete function 'alloca' called. In C++11 and later it is recommended to use std::array<> instead.\n"
"The obsolete function 'alloca' is called. In C++11 and later it is recommended to use std::array<> or "
"a dynamically allocated array instead. The function 'alloca' is dangerous for many reasons "
"(http://stackoverflow.com/questions/1018853/why-is-alloca-not-considered-good-practice and http://linux.die.net/man/3/alloca).");
} else {
if (tok->function() && tok->function()->hasBody())
continue;

const Library::WarnInfo* wi = _settings->library.getWarnInfo(tok);
if (wi) {
if (_settings->isEnabled(Severity::toString(wi->severity)) && _settings->standards.c >= wi->standards.c && _settings->standards.cpp >= wi->standards.cpp) {
reportError(tok, wi->severity, tok->str() + "Called", wi->message);
}
}
}
}
}
}
}
41 changes: 23 additions & 18 deletions lib/checknonreentrantfunctions.h → lib/checkfunctions.h
Expand Up @@ -16,55 +16,60 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/


//---------------------------------------------------------------------------
#ifndef checknonreentrantfunctionsH
#define checknonreentrantfunctionsH
#ifndef checkfunctionsH
#define checkfunctionsH
//---------------------------------------------------------------------------

#include "config.h"
#include "check.h"
#include <string>
#include <map>


/// @addtogroup Checks
/// @{

/**
* @brief Using non reentrant functions that can be replaced by their reentrant versions
* @brief Check for functions which should not be used
*/

class CPPCHECKLIB CheckNonReentrantFunctions : public Check {
class CPPCHECKLIB CheckFunctions : public Check {
public:
/** This constructor is used when registering the CheckNonReentrantFunctions */
CheckNonReentrantFunctions() : Check(myName()) {
/** This constructor is used when registering the CheckFunctions */
CheckFunctions() : Check(myName()) {
}

/** This constructor is used when running checks. */
CheckNonReentrantFunctions(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
CheckFunctions(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
: Check(myName(), tokenizer, settings, errorLogger) {
}

void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) {
CheckNonReentrantFunctions checkNonReentrantFunctions(tokenizer, settings, errorLogger);
checkNonReentrantFunctions.nonReentrantFunctions();
CheckFunctions checkFunctions(tokenizer, settings, errorLogger);
checkFunctions.check();
}

/** Check for non reentrant functions */
void nonReentrantFunctions();
/** Check for functions that should not be used */
void check();

private:
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const {
CheckFunctions c(0, settings, errorLogger);

static std::string generateErrorMessage(const std::string& function);

void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const;
for (std::map<std::string, Library::WarnInfo>::const_iterator i = settings->library.functionwarn.cbegin(); i != settings->library.functionwarn.cend(); ++i) {
c.reportError(0, Severity::style, i->first+"Called", i->second.message);
}
}

static std::string myName() {
return "Non reentrant functions";
return "Check function usage";
}

std::string classInfo() const;
std::string classInfo() const {
return "Warn if a function is called whose usage is discouraged\n";
}
};
/// @}
//---------------------------------------------------------------------------
#endif // checknonreentrantfunctionsH
#endif // checkfunctionsH
105 changes: 0 additions & 105 deletions lib/checknonreentrantfunctions.cpp

This file was deleted.

76 changes: 0 additions & 76 deletions lib/checkobsolescentfunctions.cpp

This file was deleted.

0 comments on commit 57d1196

Please sign in to comment.