Remove checks that are already covered well by most compilers (Unreachable Code; Assignment in Condition; Unused Variable).
This commit is contained in:
parent
53d02c0804
commit
42c608b6f0
@ -371,25 +371,6 @@ void CheckOther::InvalidFunctionUsage()
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// Assignment in condition
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void CheckOther::CheckIfAssignment()
|
|
||||||
{
|
|
||||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
|
||||||
{
|
|
||||||
if (Token::Match(tok, "if ( %var% = %num% )") ||
|
|
||||||
Token::Match(tok, "if ( %var% = %str% )") ||
|
|
||||||
Token::Match(tok, "if ( %var% = %var% )"))
|
|
||||||
{
|
|
||||||
_errorLogger->reportErr(ErrorMessage::ifAssignment(_tokenizer, tok));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
// Check for unsigned divisions
|
// Check for unsigned divisions
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@ -797,179 +778,6 @@ void CheckOther::CheckIncompleteStatement()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// Unreachable code below a 'return'
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void CheckOther::unreachableCode()
|
|
||||||
{
|
|
||||||
const Token *tok = _tokenizer->tokens();
|
|
||||||
while ((tok = Token::findmatch(tok, "[;{}] return")))
|
|
||||||
{
|
|
||||||
// Goto the 'return' token
|
|
||||||
tok = tok->next();
|
|
||||||
|
|
||||||
// Locate the end of the 'return' statement
|
|
||||||
while (tok && tok->str() != ";")
|
|
||||||
tok = tok->next();
|
|
||||||
while (tok && tok->next() && tok->next()->str() == ";")
|
|
||||||
tok = tok->next();
|
|
||||||
|
|
||||||
if (!tok)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// If there is a statement below the return it is unreachable
|
|
||||||
if (!Token::Match(tok, "; case|default|}|#") && !Token::Match(tok, "; %var% :")
|
|
||||||
&& (_settings._checkCodingStyle || !Token::simpleMatch(tok, "; break")))
|
|
||||||
{
|
|
||||||
_errorLogger->reportErr(ErrorMessage::unreachableCode(_tokenizer, tok->next()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// Usage of function variables
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static bool isOp(const Token *tok)
|
|
||||||
{
|
|
||||||
return bool(tok &&
|
|
||||||
(tok->str() == "&&" ||
|
|
||||||
tok->str() == "||" ||
|
|
||||||
tok->str() == "==" ||
|
|
||||||
tok->str() == "!=" ||
|
|
||||||
tok->str() == "<" ||
|
|
||||||
tok->str() == "<=" ||
|
|
||||||
tok->str() == ">" ||
|
|
||||||
tok->str() == ">=" ||
|
|
||||||
tok->str() == "<<" ||
|
|
||||||
Token::Match(tok, "[+-*/%&!~|^,[])?:]")));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckOther::functionVariableUsage()
|
|
||||||
{
|
|
||||||
// Parse all executing scopes..
|
|
||||||
const Token *tok1 = _tokenizer->tokens();
|
|
||||||
if (!tok1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
while ((tok1 = Token::findmatch(tok1->next(), ") const| {")) != NULL)
|
|
||||||
{
|
|
||||||
// Varname, usage {1=declare, 2=read, 4=write}
|
|
||||||
std::map<std::string, unsigned int> varUsage;
|
|
||||||
static const unsigned int USAGE_DECLARE = 1;
|
|
||||||
static const unsigned int USAGE_READ = 2;
|
|
||||||
static const unsigned int USAGE_WRITE = 4;
|
|
||||||
|
|
||||||
int indentlevel = 0;
|
|
||||||
for (const Token *tok = tok1->next(); tok; tok = tok->next())
|
|
||||||
{
|
|
||||||
if (tok->str() == "{")
|
|
||||||
++indentlevel;
|
|
||||||
else if (tok->str() == "}")
|
|
||||||
{
|
|
||||||
--indentlevel;
|
|
||||||
if (indentlevel <= 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (Token::Match(tok, "struct|union|class {") ||
|
|
||||||
Token::Match(tok, "struct|union|class %type% {"))
|
|
||||||
{
|
|
||||||
int indentlevel0 = indentlevel;
|
|
||||||
|
|
||||||
while (tok->str() != "{")
|
|
||||||
tok = tok->next();
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (tok->str() == "{")
|
|
||||||
indentlevel++;
|
|
||||||
else if (tok->str() == "}")
|
|
||||||
indentlevel--;
|
|
||||||
tok = tok->next();
|
|
||||||
}
|
|
||||||
while (tok && indentlevel > indentlevel0);
|
|
||||||
|
|
||||||
if (! tok)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Token::Match(tok, "[;{}] bool|char|short|int|long|float|double %var% ;|="))
|
|
||||||
varUsage[ tok->strAt(2)] = USAGE_DECLARE;
|
|
||||||
|
|
||||||
else if (Token::Match(tok, "[;{}] bool|char|short|int|long|float|double * %var% ;|="))
|
|
||||||
varUsage[ tok->strAt(3)] = USAGE_DECLARE;
|
|
||||||
|
|
||||||
else if (Token::Match(tok, "delete|return %var%"))
|
|
||||||
varUsage[ tok->strAt(1)] |= USAGE_READ;
|
|
||||||
|
|
||||||
else if (Token::Match(tok, "%var% ="))
|
|
||||||
varUsage[ tok->str()] |= USAGE_WRITE;
|
|
||||||
|
|
||||||
else if (Token::Match(tok, "else %var% ="))
|
|
||||||
varUsage[ tok->strAt(1)] |= USAGE_WRITE;
|
|
||||||
|
|
||||||
else if (Token::Match(tok, ">>|& %var%"))
|
|
||||||
varUsage[ tok->strAt(1)] |= (USAGE_WRITE | USAGE_READ);
|
|
||||||
|
|
||||||
else if ((Token::Match(tok, "[(=&!]") || isOp(tok)) && Token::Match(tok->next(), "%var%"))
|
|
||||||
varUsage[ tok->strAt(1)] |= USAGE_READ;
|
|
||||||
|
|
||||||
else if (Token::Match(tok, "-=|+=|*=|/=|&=|^= %var%") || Token::Match(tok, "|= %var%"))
|
|
||||||
varUsage[ tok->strAt(1)] |= USAGE_READ;
|
|
||||||
|
|
||||||
else if (Token::Match(tok, "%var%") && (tok->next()->str() == ")" || isOp(tok->next())))
|
|
||||||
varUsage[ tok->str()] |= USAGE_READ;
|
|
||||||
|
|
||||||
else if (Token::Match(tok, "[(,] %var% [,)]"))
|
|
||||||
varUsage[ tok->strAt(1)] |= (USAGE_WRITE | USAGE_READ);
|
|
||||||
|
|
||||||
else if (Token::Match(tok, "; %var% ;"))
|
|
||||||
varUsage[ tok->strAt(1)] |= USAGE_READ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check usage of all variables in the current scope..
|
|
||||||
for (std::map<std::string, unsigned int>::const_iterator it = varUsage.begin(); it != varUsage.end(); ++it)
|
|
||||||
{
|
|
||||||
std::string varname = it->first;
|
|
||||||
unsigned int usage = it->second;
|
|
||||||
|
|
||||||
if (!std::isalpha(varname[0]))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!(usage & USAGE_DECLARE))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (usage == USAGE_DECLARE)
|
|
||||||
{
|
|
||||||
_errorLogger->reportErr(ErrorMessage::unusedVariable(_tokenizer, tok1->next(), varname));
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (!(usage & USAGE_READ))
|
|
||||||
{
|
|
||||||
_errorLogger->reportErr(ErrorMessage::unreadVariable(_tokenizer, tok1->next(), varname));
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (!(usage & USAGE_WRITE))
|
|
||||||
{
|
|
||||||
_errorLogger->reportErr(ErrorMessage::unassignedVariable(_tokenizer, tok1->next(), varname));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
// str plus char
|
// str plus char
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -42,9 +42,6 @@ public:
|
|||||||
// Warning upon: if (condition);
|
// Warning upon: if (condition);
|
||||||
void WarningIf();
|
void WarningIf();
|
||||||
|
|
||||||
// Assignment in condition
|
|
||||||
void CheckIfAssignment();
|
|
||||||
|
|
||||||
// Invalid function usage..
|
// Invalid function usage..
|
||||||
void InvalidFunctionUsage();
|
void InvalidFunctionUsage();
|
||||||
|
|
||||||
@ -66,12 +63,6 @@ public:
|
|||||||
// Incomplete statement. A statement that only contains a constant or variable
|
// Incomplete statement. A statement that only contains a constant or variable
|
||||||
void CheckIncompleteStatement();
|
void CheckIncompleteStatement();
|
||||||
|
|
||||||
/** Unreachable code below a 'return' */
|
|
||||||
void unreachableCode();
|
|
||||||
|
|
||||||
/** Unused function variables */
|
|
||||||
void functionVariableUsage();
|
|
||||||
|
|
||||||
/** str plus char */
|
/** str plus char */
|
||||||
void strPlusChar();
|
void strPlusChar();
|
||||||
|
|
||||||
|
@ -251,10 +251,6 @@ void CppCheck::checkFile(const std::string &code, const char FileName[])
|
|||||||
if (ErrorMessage::charArrayIndex(_settings) || ErrorMessage::charBitOp(_settings))
|
if (ErrorMessage::charArrayIndex(_settings) || ErrorMessage::charBitOp(_settings))
|
||||||
checkOther.CheckCharVariable();
|
checkOther.CheckCharVariable();
|
||||||
|
|
||||||
// Usage of local variables
|
|
||||||
if (ErrorMessage::unusedVariable(_settings))
|
|
||||||
checkOther.functionVariableUsage();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_tokenizer.simplifyTokenList();
|
_tokenizer.simplifyTokenList();
|
||||||
@ -283,10 +279,6 @@ void CppCheck::checkFile(const std::string &code, const char FileName[])
|
|||||||
if (ErrorMessage::arrayIndexOutOfBounds(_settings) && ErrorMessage::bufferOverrun(_settings))
|
if (ErrorMessage::arrayIndexOutOfBounds(_settings) && ErrorMessage::bufferOverrun(_settings))
|
||||||
checkBufferOverrun.bufferOverrun();
|
checkBufferOverrun.bufferOverrun();
|
||||||
|
|
||||||
// Check for "if (a=b)"
|
|
||||||
if (ErrorMessage::ifAssignment(_settings))
|
|
||||||
checkOther.CheckIfAssignment();
|
|
||||||
|
|
||||||
// Dangerous functions, such as 'gets' and 'scanf'
|
// Dangerous functions, such as 'gets' and 'scanf'
|
||||||
checkBufferOverrun.dangerousFunctions();
|
checkBufferOverrun.dangerousFunctions();
|
||||||
|
|
||||||
@ -323,10 +315,6 @@ void CppCheck::checkFile(const std::string &code, const char FileName[])
|
|||||||
if (ErrorMessage::unusedStructMember(_settings))
|
if (ErrorMessage::unusedStructMember(_settings))
|
||||||
checkOther.CheckStructMemberUsage();
|
checkOther.CheckStructMemberUsage();
|
||||||
|
|
||||||
// Unreachable code below a 'return' statement
|
|
||||||
if (ErrorMessage::unreachableCode())
|
|
||||||
checkOther.unreachableCode();
|
|
||||||
|
|
||||||
// Check if a constant function parameter is passed by value
|
// Check if a constant function parameter is passed by value
|
||||||
if (ErrorMessage::passedByValue())
|
if (ErrorMessage::passedByValue())
|
||||||
checkOther.CheckConstantFunctionParameter();
|
checkOther.CheckConstantFunctionParameter();
|
||||||
|
@ -1,359 +1,314 @@
|
|||||||
/*
|
/*
|
||||||
* Cppcheck - A tool for static C/C++ code analysis
|
* Cppcheck - A tool for static C/C++ code analysis
|
||||||
* Copyright (C) 2007-2009 Daniel Marjamäki, Reijo Tomperi, Nicolas Le Cam,
|
* Copyright (C) 2007-2009 Daniel Marjamäki, Reijo Tomperi, Nicolas Le Cam,
|
||||||
* Leandro Penz, Kimmo Varis
|
* Leandro Penz, Kimmo Varis
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/
|
* along with this program. If not, see <http://www.gnu.org/licenses/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY MACHINE, SEE ../tools/errmsg.cpp !
|
// THIS FILE IS GENERATED BY MACHINE, SEE ../tools/errmsg.cpp !
|
||||||
|
|
||||||
#ifndef errormessageH
|
#ifndef errormessageH
|
||||||
#define errormessageH
|
#define errormessageH
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
class Token;
|
class Token;
|
||||||
class Tokenizer;
|
class Tokenizer;
|
||||||
class ErrorMessage
|
class ErrorMessage
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
ErrorMessage() { }
|
ErrorMessage() { }
|
||||||
static std::string msg1(const Tokenizer *tokenizer, const Token *Location);
|
static std::string msg1(const Tokenizer *tokenizer, const Token *Location);
|
||||||
public:
|
public:
|
||||||
static std::string arrayIndexOutOfBounds(const Tokenizer *tokenizer, const Token *Location)
|
static std::string arrayIndexOutOfBounds(const Tokenizer *tokenizer, const Token *Location)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Array index out of bounds";
|
return msg1(tokenizer, Location) + "Array index out of bounds";
|
||||||
}
|
}
|
||||||
static bool arrayIndexOutOfBounds(const Settings &s)
|
static bool arrayIndexOutOfBounds(const Settings &s)
|
||||||
{
|
{
|
||||||
return s._showAll;
|
return s._showAll;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string bufferOverrun(const Tokenizer *tokenizer, const Token *Location)
|
static std::string bufferOverrun(const Tokenizer *tokenizer, const Token *Location)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Buffer overrun";
|
return msg1(tokenizer, Location) + "Buffer overrun";
|
||||||
}
|
}
|
||||||
static bool bufferOverrun(const Settings &s)
|
static bool bufferOverrun(const Settings &s)
|
||||||
{
|
{
|
||||||
return s._showAll;
|
return s._showAll;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string outOfBounds(const Tokenizer *tokenizer, const Token *Location, const std::string &what)
|
static std::string outOfBounds(const Tokenizer *tokenizer, const Token *Location, const std::string &what)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "" + what + " is out of bounds";
|
return msg1(tokenizer, Location) + "" + what + " is out of bounds";
|
||||||
}
|
}
|
||||||
static bool outOfBounds()
|
static bool outOfBounds()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string noConstructor(const Tokenizer *tokenizer, const Token *Location, const std::string &classname)
|
static std::string noConstructor(const Tokenizer *tokenizer, const Token *Location, const std::string &classname)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "The class '" + classname + "' has no constructor";
|
return msg1(tokenizer, Location) + "The class '" + classname + "' has no constructor";
|
||||||
}
|
}
|
||||||
static bool noConstructor(const Settings &s)
|
static bool noConstructor(const Settings &s)
|
||||||
{
|
{
|
||||||
return s._checkCodingStyle;
|
return s._checkCodingStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string uninitVar(const Tokenizer *tokenizer, const Token *Location, const std::string &classname, const std::string &varname)
|
static std::string uninitVar(const Tokenizer *tokenizer, const Token *Location, const std::string &classname, const std::string &varname)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Uninitialized member variable '" + classname + "::" + varname + "'";
|
return msg1(tokenizer, Location) + "Uninitialized member variable '" + classname + "::" + varname + "'";
|
||||||
}
|
}
|
||||||
static bool uninitVar()
|
static bool uninitVar()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string unusedPrivateFunction(const Tokenizer *tokenizer, const Token *Location, const std::string &classname, const std::string &funcname)
|
static std::string unusedPrivateFunction(const Tokenizer *tokenizer, const Token *Location, const std::string &classname, const std::string &funcname)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Unused private function '" + classname + "::" + funcname + "'";
|
return msg1(tokenizer, Location) + "Unused private function '" + classname + "::" + funcname + "'";
|
||||||
}
|
}
|
||||||
static bool unusedPrivateFunction(const Settings &s)
|
static bool unusedPrivateFunction(const Settings &s)
|
||||||
{
|
{
|
||||||
return s._checkCodingStyle;
|
return s._checkCodingStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string memsetClass(const Tokenizer *tokenizer, const Token *Location, const std::string &memfunc)
|
static std::string memsetClass(const Tokenizer *tokenizer, const Token *Location, const std::string &memfunc)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Using '" + memfunc + "' on class";
|
return msg1(tokenizer, Location) + "Using '" + memfunc + "' on class";
|
||||||
}
|
}
|
||||||
static bool memsetClass()
|
static bool memsetClass()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string memsetStruct(const Tokenizer *tokenizer, const Token *Location, const std::string &memfunc, const std::string &classname)
|
static std::string memsetStruct(const Tokenizer *tokenizer, const Token *Location, const std::string &memfunc, const std::string &classname)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Using '" + memfunc + "' on struct that contains a 'std::" + classname + "'";
|
return msg1(tokenizer, Location) + "Using '" + memfunc + "' on struct that contains a 'std::" + classname + "'";
|
||||||
}
|
}
|
||||||
static bool memsetStruct()
|
static bool memsetStruct()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string operatorEq(const Tokenizer *tokenizer, const Token *Location)
|
static std::string operatorEq(const Tokenizer *tokenizer, const Token *Location)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "'operator=' should return something";
|
return msg1(tokenizer, Location) + "'operator=' should return something";
|
||||||
}
|
}
|
||||||
static bool operatorEq(const Settings &s)
|
static bool operatorEq(const Settings &s)
|
||||||
{
|
{
|
||||||
return s._checkCodingStyle;
|
return s._checkCodingStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string virtualDestructor(const Tokenizer *tokenizer, const Token *Location, const std::string &Base, const std::string &Derived)
|
static std::string virtualDestructor(const Tokenizer *tokenizer, const Token *Location, const std::string &Base, const std::string &Derived)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Class " + Base + " which is inherited by class " + Derived + " does not have a virtual destructor";
|
return msg1(tokenizer, Location) + "Class " + Base + " which is inherited by class " + Derived + " does not have a virtual destructor";
|
||||||
}
|
}
|
||||||
static bool virtualDestructor()
|
static bool virtualDestructor()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string unusedFunction(const std::string &filename, const std::string &funcname)
|
static std::string unusedFunction(const std::string &filename, const std::string &funcname)
|
||||||
{
|
{
|
||||||
return "[" + filename + "]: The function '" + funcname + "' is never used";
|
return "[" + filename + "]: The function '" + funcname + "' is never used";
|
||||||
}
|
}
|
||||||
static bool unusedFunction(const Settings &s)
|
static bool unusedFunction(const Settings &s)
|
||||||
{
|
{
|
||||||
return s._showAll & s._checkCodingStyle;
|
return s._showAll & s._checkCodingStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string mismatchAllocDealloc(const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
|
static std::string mismatchAllocDealloc(const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Mismatching allocation and deallocation: " + varname + "";
|
return msg1(tokenizer, Location) + "Mismatching allocation and deallocation: " + varname + "";
|
||||||
}
|
}
|
||||||
static bool mismatchAllocDealloc()
|
static bool mismatchAllocDealloc()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string memleak(const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
|
static std::string memleak(const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Memory leak: " + varname + "";
|
return msg1(tokenizer, Location) + "Memory leak: " + varname + "";
|
||||||
}
|
}
|
||||||
static bool memleak()
|
static bool memleak()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string resourceLeak(const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
|
static std::string resourceLeak(const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Resource leak: " + varname + "";
|
return msg1(tokenizer, Location) + "Resource leak: " + varname + "";
|
||||||
}
|
}
|
||||||
static bool resourceLeak()
|
static bool resourceLeak()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string deallocDealloc(const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
|
static std::string deallocDealloc(const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Deallocating a deallocated pointer: " + varname + "";
|
return msg1(tokenizer, Location) + "Deallocating a deallocated pointer: " + varname + "";
|
||||||
}
|
}
|
||||||
static bool deallocDealloc()
|
static bool deallocDealloc()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string cstyleCast(const Tokenizer *tokenizer, const Token *Location)
|
static std::string cstyleCast(const Tokenizer *tokenizer, const Token *Location)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "C-style pointer casting";
|
return msg1(tokenizer, Location) + "C-style pointer casting";
|
||||||
}
|
}
|
||||||
static bool cstyleCast(const Settings &s)
|
static bool cstyleCast(const Settings &s)
|
||||||
{
|
{
|
||||||
return s._checkCodingStyle;
|
return s._checkCodingStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string redundantIfDelete0(const Tokenizer *tokenizer, const Token *Location)
|
static std::string redundantIfDelete0(const Tokenizer *tokenizer, const Token *Location)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Redundant condition. It is safe to deallocate a NULL pointer";
|
return msg1(tokenizer, Location) + "Redundant condition. It is safe to deallocate a NULL pointer";
|
||||||
}
|
}
|
||||||
static bool redundantIfDelete0(const Settings &s)
|
static bool redundantIfDelete0(const Settings &s)
|
||||||
{
|
{
|
||||||
return s._checkCodingStyle;
|
return s._checkCodingStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string redundantIfRemove(const Tokenizer *tokenizer, const Token *Location)
|
static std::string redundantIfRemove(const Tokenizer *tokenizer, const Token *Location)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Redundant condition. The remove function in the STL will not do anything if element doesn't exist";
|
return msg1(tokenizer, Location) + "Redundant condition. The remove function in the STL will not do anything if element doesn't exist";
|
||||||
}
|
}
|
||||||
static bool redundantIfRemove(const Settings &s)
|
static bool redundantIfRemove(const Settings &s)
|
||||||
{
|
{
|
||||||
return s._checkCodingStyle;
|
return s._checkCodingStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string dangerousUsageStrtol(const Tokenizer *tokenizer, const Token *Location)
|
static std::string dangerousUsageStrtol(const Tokenizer *tokenizer, const Token *Location)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Invalid radix in call to strtol or strtoul. Must be 0 or 2-36";
|
return msg1(tokenizer, Location) + "Invalid radix in call to strtol or strtoul. Must be 0 or 2-36";
|
||||||
}
|
}
|
||||||
static bool dangerousUsageStrtol()
|
static bool dangerousUsageStrtol()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string ifNoAction(const Tokenizer *tokenizer, const Token *Location)
|
static std::string ifNoAction(const Tokenizer *tokenizer, const Token *Location)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Found redundant if condition - 'if (condition);'";
|
return msg1(tokenizer, Location) + "Found redundant if condition - 'if (condition);'";
|
||||||
}
|
}
|
||||||
static bool ifNoAction(const Settings &s)
|
static bool ifNoAction(const Settings &s)
|
||||||
{
|
{
|
||||||
return s._checkCodingStyle;
|
return s._checkCodingStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string sprintfOverlappingData(const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
|
static std::string sprintfOverlappingData(const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Overlapping data buffer " + varname + "";
|
return msg1(tokenizer, Location) + "Overlapping data buffer " + varname + "";
|
||||||
}
|
}
|
||||||
static bool sprintfOverlappingData()
|
static bool sprintfOverlappingData()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string udivError(const Tokenizer *tokenizer, const Token *Location)
|
static std::string udivError(const Tokenizer *tokenizer, const Token *Location)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Unsigned division. The result will be wrong.";
|
return msg1(tokenizer, Location) + "Unsigned division. The result will be wrong.";
|
||||||
}
|
}
|
||||||
static bool udivError()
|
static bool udivError()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string udivWarning(const Tokenizer *tokenizer, const Token *Location)
|
static std::string udivWarning(const Tokenizer *tokenizer, const Token *Location)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Warning: Division with signed and unsigned operators";
|
return msg1(tokenizer, Location) + "Warning: Division with signed and unsigned operators";
|
||||||
}
|
}
|
||||||
static bool udivWarning(const Settings &s)
|
static bool udivWarning(const Settings &s)
|
||||||
{
|
{
|
||||||
return s._showAll & s._checkCodingStyle;
|
return s._showAll & s._checkCodingStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string unusedStructMember(const Tokenizer *tokenizer, const Token *Location, const std::string &structname, const std::string &varname)
|
static std::string unusedStructMember(const Tokenizer *tokenizer, const Token *Location, const std::string &structname, const std::string &varname)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "struct or union member '" + structname + "::" + varname + "' is never used";
|
return msg1(tokenizer, Location) + "struct or union member '" + structname + "::" + varname + "' is never used";
|
||||||
}
|
}
|
||||||
static bool unusedStructMember(const Settings &s)
|
static bool unusedStructMember(const Settings &s)
|
||||||
{
|
{
|
||||||
return s._checkCodingStyle;
|
return s._checkCodingStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string unreachableCode(const Tokenizer *tokenizer, const Token *Location)
|
static std::string passedByValue(const Tokenizer *tokenizer, const Token *Location, const std::string &parname)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Unreachable code below a 'return'";
|
return msg1(tokenizer, Location) + "Function parameter '" + parname + "' is passed by value. It could be passed by reference instead.";
|
||||||
}
|
}
|
||||||
static bool unreachableCode()
|
static bool passedByValue()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string passedByValue(const Tokenizer *tokenizer, const Token *Location, const std::string &parname)
|
static std::string constStatement(const Tokenizer *tokenizer, const Token *Location, const std::string &type)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Function parameter '" + parname + "' is passed by value. It could be passed by reference instead.";
|
return msg1(tokenizer, Location) + "Redundant code: Found a statement that begins with " + type + " constant";
|
||||||
}
|
}
|
||||||
static bool passedByValue()
|
static bool constStatement(const Settings &s)
|
||||||
{
|
{
|
||||||
return true;
|
return s._checkCodingStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string unusedVariable(const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
|
static std::string charArrayIndex(const Tokenizer *tokenizer, const Token *Location)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Unused variable '" + varname + "'";
|
return msg1(tokenizer, Location) + "Warning - using char variable as array index";
|
||||||
}
|
}
|
||||||
static bool unusedVariable(const Settings &s)
|
static bool charArrayIndex(const Settings &s)
|
||||||
{
|
{
|
||||||
return s._checkCodingStyle;
|
return s._checkCodingStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string unreadVariable(const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
|
static std::string charBitOp(const Tokenizer *tokenizer, const Token *Location)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Variable '" + varname + "' is assigned a value that is never used";
|
return msg1(tokenizer, Location) + "Warning - using char variable in bit operation";
|
||||||
}
|
}
|
||||||
static bool unreadVariable(const Settings &s)
|
static bool charBitOp(const Settings &s)
|
||||||
{
|
{
|
||||||
return s._checkCodingStyle;
|
return s._checkCodingStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string unassignedVariable(const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
|
static std::string variableScope(const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Variable '" + varname + "' is not assigned a value";
|
return msg1(tokenizer, Location) + "The scope of the variable " + varname + " can be limited";
|
||||||
}
|
}
|
||||||
static bool unassignedVariable(const Settings &s)
|
static bool variableScope()
|
||||||
{
|
{
|
||||||
return s._checkCodingStyle;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string constStatement(const Tokenizer *tokenizer, const Token *Location, const std::string &type)
|
static std::string conditionAlwaysTrueFalse(const Tokenizer *tokenizer, const Token *Location, const std::string &truefalse)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Redundant code: Found a statement that begins with " + type + " constant";
|
return msg1(tokenizer, Location) + "Condition is always " + truefalse + "";
|
||||||
}
|
}
|
||||||
static bool constStatement(const Settings &s)
|
static bool conditionAlwaysTrueFalse(const Settings &s)
|
||||||
{
|
{
|
||||||
return s._checkCodingStyle;
|
return s._checkCodingStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string charArrayIndex(const Tokenizer *tokenizer, const Token *Location)
|
static std::string strPlusChar(const Tokenizer *tokenizer, const Token *Location)
|
||||||
{
|
{
|
||||||
return msg1(tokenizer, Location) + "Warning - using char variable as array index";
|
return msg1(tokenizer, Location) + "Unusual pointer arithmetic";
|
||||||
}
|
}
|
||||||
static bool charArrayIndex(const Settings &s)
|
static bool strPlusChar()
|
||||||
{
|
{
|
||||||
return s._checkCodingStyle;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string charBitOp(const Tokenizer *tokenizer, const Token *Location)
|
};
|
||||||
{
|
#endif
|
||||||
return msg1(tokenizer, Location) + "Warning - using char variable in bit operation";
|
|
||||||
}
|
|
||||||
static bool charBitOp(const Settings &s)
|
|
||||||
{
|
|
||||||
return s._checkCodingStyle;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string variableScope(const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
|
|
||||||
{
|
|
||||||
return msg1(tokenizer, Location) + "The scope of the variable " + varname + " can be limited";
|
|
||||||
}
|
|
||||||
static bool variableScope()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string ifAssignment(const Tokenizer *tokenizer, const Token *Location)
|
|
||||||
{
|
|
||||||
return msg1(tokenizer, Location) + "Assignment in if-condition";
|
|
||||||
}
|
|
||||||
static bool ifAssignment(const Settings &s)
|
|
||||||
{
|
|
||||||
return s._checkCodingStyle;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string conditionAlwaysTrueFalse(const Tokenizer *tokenizer, const Token *Location, const std::string &truefalse)
|
|
||||||
{
|
|
||||||
return msg1(tokenizer, Location) + "Condition is always " + truefalse + "";
|
|
||||||
}
|
|
||||||
static bool conditionAlwaysTrueFalse(const Settings &s)
|
|
||||||
{
|
|
||||||
return s._checkCodingStyle;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string strPlusChar(const Tokenizer *tokenizer, const Token *Location)
|
|
||||||
{
|
|
||||||
return msg1(tokenizer, Location) + "Unusual pointer arithmetic";
|
|
||||||
}
|
|
||||||
static bool strPlusChar()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
@ -59,26 +59,6 @@ private:
|
|||||||
TEST_CASE(structmember3);
|
TEST_CASE(structmember3);
|
||||||
TEST_CASE(structmember4);
|
TEST_CASE(structmember4);
|
||||||
TEST_CASE(structmember5);
|
TEST_CASE(structmember5);
|
||||||
|
|
||||||
TEST_CASE(localvar1);
|
|
||||||
TEST_CASE(localvar2);
|
|
||||||
TEST_CASE(localvar3);
|
|
||||||
TEST_CASE(localvar4);
|
|
||||||
TEST_CASE(localvar5);
|
|
||||||
|
|
||||||
// Don't give false positives for variables in structs/unions
|
|
||||||
TEST_CASE(localvarStruct1);
|
|
||||||
TEST_CASE(localvarStruct2);
|
|
||||||
TEST_CASE(localvarStruct3);
|
|
||||||
TEST_CASE(localvarStruct4); // Ticket #31: sigsegv on incomplete struct
|
|
||||||
|
|
||||||
TEST_CASE(localvarOp); // Usage with arithmetic operators
|
|
||||||
TEST_CASE(localvarInvert); // Usage with inverted variable
|
|
||||||
TEST_CASE(localvarIf); // Usage in if
|
|
||||||
TEST_CASE(localvarIfElse); // return tmp1 ? tmp2 : tmp3;
|
|
||||||
TEST_CASE(localvarOpAssign); // a |= b;
|
|
||||||
TEST_CASE(localvarFor); // for ( ; var; )
|
|
||||||
TEST_CASE(localvarShift); // 1 >> var
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void structmember1()
|
void structmember1()
|
||||||
@ -170,203 +150,6 @@ private:
|
|||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS(std::string(""), errout.str());
|
ASSERT_EQUALS(std::string(""), errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void functionVariableUsage(const char code[])
|
|
||||||
{
|
|
||||||
// Tokenize..
|
|
||||||
Tokenizer tokenizer;
|
|
||||||
std::istringstream istr(code);
|
|
||||||
tokenizer.tokenize(istr, "test.cpp");
|
|
||||||
tokenizer.simplifyTokenList();
|
|
||||||
|
|
||||||
// Clear the error buffer..
|
|
||||||
errout.str("");
|
|
||||||
|
|
||||||
// Check for unused variables..
|
|
||||||
CheckOther checkOther(&tokenizer, Settings(), this);
|
|
||||||
checkOther.functionVariableUsage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void localvar1()
|
|
||||||
{
|
|
||||||
functionVariableUsage("void foo()\n"
|
|
||||||
"{\n"
|
|
||||||
" int i = 0;\n"
|
|
||||||
"}\n");
|
|
||||||
ASSERT_EQUALS(std::string("[test.cpp:2]: Variable 'i' is assigned a value that is never used\n"), errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void localvar2()
|
|
||||||
{
|
|
||||||
functionVariableUsage("void foo()\n"
|
|
||||||
"{\n"
|
|
||||||
" int i;\n"
|
|
||||||
" return i;\n"
|
|
||||||
"}\n");
|
|
||||||
ASSERT_EQUALS(std::string("[test.cpp:2]: Variable 'i' is not assigned a value\n"), errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void localvar3()
|
|
||||||
{
|
|
||||||
functionVariableUsage("void foo()\n"
|
|
||||||
"{\n"
|
|
||||||
" int i;\n"
|
|
||||||
" if ( abc )\n"
|
|
||||||
" ;\n"
|
|
||||||
" else i = 0;\n"
|
|
||||||
"}\n");
|
|
||||||
ASSERT_EQUALS(std::string("[test.cpp:2]: Variable 'i' is assigned a value that is never used\n"), errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void localvar4()
|
|
||||||
{
|
|
||||||
functionVariableUsage("void foo()\n"
|
|
||||||
"{\n"
|
|
||||||
" int i = 0;\n"
|
|
||||||
" f(i);\n"
|
|
||||||
"}\n");
|
|
||||||
ASSERT_EQUALS(std::string(""), errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void localvar5()
|
|
||||||
{
|
|
||||||
functionVariableUsage("void foo()\n"
|
|
||||||
"{\n"
|
|
||||||
" int a = 0;\n"
|
|
||||||
" b = (char)a;\n"
|
|
||||||
"}\n");
|
|
||||||
ASSERT_EQUALS(std::string(""), errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void localvarStruct1()
|
|
||||||
{
|
|
||||||
functionVariableUsage("void foo()\n"
|
|
||||||
"{\n"
|
|
||||||
" static const struct{ int x, y, w, h; } bounds = {1,2,3,4};\n"
|
|
||||||
" return bounds.x + bounds.y + bounds.w + bounds.h;\n"
|
|
||||||
"}\n");
|
|
||||||
ASSERT_EQUALS(std::string(""), errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void localvarStruct2()
|
|
||||||
{
|
|
||||||
functionVariableUsage("void foo()\n"
|
|
||||||
"{\n"
|
|
||||||
" struct ABC { int a, b, c; };\n"
|
|
||||||
" struct ABC abc = { 1, 2, 3 };\n"
|
|
||||||
"}\n");
|
|
||||||
ASSERT_EQUALS(std::string(""), errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void localvarStruct3()
|
|
||||||
{
|
|
||||||
functionVariableUsage("void foo()\n"
|
|
||||||
"{\n"
|
|
||||||
" int a = 10;\n"
|
|
||||||
" union { struct { unsigned char x; }; unsigned char z; };\n"
|
|
||||||
" do {\n"
|
|
||||||
" func();\n"
|
|
||||||
" } while(a--);\n"
|
|
||||||
"}\n");
|
|
||||||
ASSERT_EQUALS(std::string(""), errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void localvarStruct4()
|
|
||||||
{
|
|
||||||
/* This must not SIGSEGV: */
|
|
||||||
functionVariableUsage("void foo()\n"
|
|
||||||
"{\n"
|
|
||||||
" struct { \n");
|
|
||||||
errout.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void localvarOp()
|
|
||||||
{
|
|
||||||
const char op[] = "+-*/%&|^";
|
|
||||||
for (const char *p = op; *p; ++p)
|
|
||||||
{
|
|
||||||
std::string code("int main()\n"
|
|
||||||
"{\n"
|
|
||||||
" int tmp = 10;\n"
|
|
||||||
" return 123 " + std::string(1, *p) + " tmp;\n"
|
|
||||||
"}\n");
|
|
||||||
functionVariableUsage(code.c_str());
|
|
||||||
ASSERT_EQUALS(std::string(""), errout.str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void localvarInvert()
|
|
||||||
{
|
|
||||||
functionVariableUsage("int main()\n"
|
|
||||||
"{\n"
|
|
||||||
" int tmp = 10;\n"
|
|
||||||
" return ~tmp;\n"
|
|
||||||
"}\n");
|
|
||||||
ASSERT_EQUALS(std::string(""), errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void localvarIf()
|
|
||||||
{
|
|
||||||
functionVariableUsage("int main()\n"
|
|
||||||
"{\n"
|
|
||||||
" int tmp = 10;\n"
|
|
||||||
" if ( tmp )\n"
|
|
||||||
" return 1;\n"
|
|
||||||
" return 0;\n"
|
|
||||||
"}\n");
|
|
||||||
ASSERT_EQUALS(std::string(""), errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void localvarIfElse()
|
|
||||||
{
|
|
||||||
functionVariableUsage("int foo()\n"
|
|
||||||
"{\n"
|
|
||||||
" int tmp1 = 1;\n"
|
|
||||||
" int tmp2 = 2;\n"
|
|
||||||
" int tmp3 = 3;\n"
|
|
||||||
" return tmp1 ? tmp2 : tmp3;\n"
|
|
||||||
"}\n");
|
|
||||||
ASSERT_EQUALS(std::string(""), errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void localvarOpAssign()
|
|
||||||
{
|
|
||||||
functionVariableUsage("void foo()\n"
|
|
||||||
"{\n"
|
|
||||||
" int a = 1;\n"
|
|
||||||
" int b = 2;\n"
|
|
||||||
" a |= b;\n"
|
|
||||||
"}\n");
|
|
||||||
ASSERT_EQUALS(std::string("[test.cpp:2]: Variable 'a' is assigned a value that is never used\n"), errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void localvarFor()
|
|
||||||
{
|
|
||||||
functionVariableUsage("void foo()\n"
|
|
||||||
"{\n"
|
|
||||||
" int a = 1;\n"
|
|
||||||
" for (;a;);\n"
|
|
||||||
"}\n");
|
|
||||||
ASSERT_EQUALS(std::string(""), errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void localvarShift()
|
|
||||||
{
|
|
||||||
functionVariableUsage("int foo()\n"
|
|
||||||
"{\n"
|
|
||||||
" int var = 1;\n"
|
|
||||||
" return 1 >> var;\n"
|
|
||||||
"}\n");
|
|
||||||
ASSERT_EQUALS(std::string(""), errout.str());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_TEST(TestUnusedVar)
|
REGISTER_TEST(TestUnusedVar)
|
||||||
|
@ -86,16 +86,11 @@ int main()
|
|||||||
err.push_back(Message("udivError", Message::always, "Unsigned division. The result will be wrong."));
|
err.push_back(Message("udivError", Message::always, "Unsigned division. The result will be wrong."));
|
||||||
err.push_back(Message("udivWarning", Message::style_all, "Warning: Division with signed and unsigned operators"));
|
err.push_back(Message("udivWarning", Message::style_all, "Warning: Division with signed and unsigned operators"));
|
||||||
err.push_back(Message("unusedStructMember", Message::style, "struct or union member '%1::%2' is never used", "structname", "varname"));
|
err.push_back(Message("unusedStructMember", Message::style, "struct or union member '%1::%2' is never used", "structname", "varname"));
|
||||||
err.push_back(Message("unreachableCode", Message::always, "Unreachable code below a 'return'"));
|
|
||||||
err.push_back(Message("passedByValue", Message::always, "Function parameter '%1' is passed by value. It could be passed by reference instead.", "parname"));
|
err.push_back(Message("passedByValue", Message::always, "Function parameter '%1' is passed by value. It could be passed by reference instead.", "parname"));
|
||||||
err.push_back(Message("unusedVariable", Message::style, "Unused variable '%1'", "varname"));
|
|
||||||
err.push_back(Message("unreadVariable", Message::style, "Variable '%1' is assigned a value that is never used", "varname"));
|
|
||||||
err.push_back(Message("unassignedVariable", Message::style, "Variable '%1' is not assigned a value", "varname"));
|
|
||||||
err.push_back(Message("constStatement", Message::style, "Redundant code: Found a statement that begins with %1 constant", "type"));
|
err.push_back(Message("constStatement", Message::style, "Redundant code: Found a statement that begins with %1 constant", "type"));
|
||||||
err.push_back(Message("charArrayIndex", Message::style, "Warning - using char variable as array index"));
|
err.push_back(Message("charArrayIndex", Message::style, "Warning - using char variable as array index"));
|
||||||
err.push_back(Message("charBitOp", Message::style, "Warning - using char variable in bit operation"));
|
err.push_back(Message("charBitOp", Message::style, "Warning - using char variable in bit operation"));
|
||||||
err.push_back(Message("variableScope", Message::never, "The scope of the variable %1 can be limited", "varname"));
|
err.push_back(Message("variableScope", Message::never, "The scope of the variable %1 can be limited", "varname"));
|
||||||
err.push_back(Message("ifAssignment", Message::style, "Assignment in if-condition"));
|
|
||||||
err.push_back(Message("conditionAlwaysTrueFalse", Message::style, "Condition is always %1", "truefalse"));
|
err.push_back(Message("conditionAlwaysTrueFalse", Message::style, "Condition is always %1", "truefalse"));
|
||||||
err.push_back(Message("strPlusChar", Message::always, "Unusual pointer arithmetic"));
|
err.push_back(Message("strPlusChar", Message::always, "Unusual pointer arithmetic"));
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user