- Print "inconclusive" tag in cli
- Fixed inconclusive handling in checkbufferoverrun.cpp
- Merged reportInconclusiveError into reportError by adding an additional parameter "bool inconclusive" which is false per default
This commit is contained in:
PKEuS 2012-05-06 10:37:41 -07:00
parent 6ef92c4fd7
commit ec00824fd3
14 changed files with 298 additions and 332 deletions

View File

@ -114,40 +114,13 @@ protected:
ErrorLogger * const _errorLogger;
/** report an error */
void reportError(const Token *tok, const Severity::SeverityType severity, const std::string &id, const std::string &msg) {
std::list<const Token *> callstack;
if (tok)
callstack.push_back(tok);
reportError(callstack, severity, id, msg);
void reportError(const Token *tok, const Severity::SeverityType severity, const std::string &id, const std::string &msg, bool inconclusive = false) {
std::list<const Token *> callstack(1, tok);
reportError(callstack, severity, id, msg, inconclusive);
}
/** report an error */
void reportError(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string& msg) {
reportError(callstack, severity, id, msg, false);
}
/** report an inconclusive error */
void reportInconclusiveError(const Token *tok, const Severity::SeverityType severity, const std::string &id, const std::string &msg) {
std::list<const Token *> callstack;
if (tok)
callstack.push_back(tok);
reportInconclusiveError(callstack, severity, id, msg);
}
/** report an inconclusive error */
void reportInconclusiveError(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string& msg) {
reportError(callstack, severity, id, msg, true);
}
private:
const std::string _name;
/** disabled assignment operator */
void operator=(const Check &);
/** report an error */
void reportError(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string& msg, bool inconclusive) {
void reportError(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string& msg, bool inconclusive = false) {
ErrorLogger::ErrorMessage errmsg(callstack, _tokenizer?&_tokenizer->list:0, severity, id, msg, inconclusive);
if (_errorLogger)
_errorLogger->reportErr(errmsg);
@ -155,6 +128,11 @@ private:
reportError(errmsg);
}
private:
const std::string _name;
/** disabled assignment operator */
void operator=(const Check &);
};
namespace std {

View File

@ -208,12 +208,12 @@ void CheckAutoVariables::errorAutoVariableAssignment(const Token *tok, bool inco
"stack is freed when the function ends. So the pointer to a local variable "
"is invalid after the function ends.");
} else {
reportInconclusiveError(tok, Severity::error, "autoVariables",
"Inconclusive: Assigning address of local auto-variable to a function parameter.\n"
"Inconclusive: function parameter takes the address of a local auto-variable. "
"Local auto-variables are reserved from the stack. And the stack is freed when "
"the function ends. The address is invalid after the function ends and it "
"might 'leak' from the function through the parameter.");
reportError(tok, Severity::error, "autoVariables",
"Assigning address of local auto-variable to a function parameter.\n"
"Function parameter takes the address of a local auto-variable. "
"Local auto-variables are reserved from the stack. And the stack is freed when "
"the function ends. The address is invalid after the function ends and it "
"might 'leak' from the function through the parameter.", true);
}
}

View File

@ -112,7 +112,7 @@ void CheckBufferOverrun::possibleReadlinkBufferOverrunError(const Token* tok, co
funcname + "() might return the full size of '" + varname + "'. Lower the supplied size by one. "
"If a " + varname + "[len] = '\\0'; statement follows, it will overrun the buffer.";
reportInconclusiveError(tok, Severity::warning, "possibleReadlinkBufferOverrun", errmsg);
reportError(tok, Severity::warning, "possibleReadlinkBufferOverrun", errmsg, true);
}
void CheckBufferOverrun::strncatUsageError(const Token *tok)
@ -172,7 +172,7 @@ void CheckBufferOverrun::bufferNotZeroTerminatedError(const Token *tok, const st
"The buffer '" + varname + "' is not zero-terminated after the call to " + function + "(). "
"This will cause bugs later in the code if the code assumes the buffer is zero-terminated.";
reportInconclusiveError(tok, Severity::warning, "bufferNotZeroTerminated", errmsg);
reportError(tok, Severity::warning, "bufferNotZeroTerminated", errmsg, true);
}
//---------------------------------------------------------------------------

View File

@ -1425,13 +1425,13 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func)
void CheckClass::checkConstError(const Token *tok, const std::string &classname, const std::string &funcname)
{
reportInconclusiveError(tok, Severity::style, "functionConst",
"Technically the member function '" + classname + "::" + funcname + "' can be const.\n"
"The member function '" + classname + "::" + funcname + "' can be made a const "
"function. Making this function const function should not cause compiler errors. "
"Even though the function can be made const function technically it may not make "
"sense conceptually. Think about your design and task of the function first - is "
"it a function that must not change object internal state?");
reportError(tok, Severity::style, "functionConst",
"Technically the member function '" + classname + "::" + funcname + "' can be const.\n"
"The member function '" + classname + "::" + funcname + "' can be made a const "
"function. Making this function const function should not cause compiler errors. "
"Even though the function can be made const function technically it may not make "
"sense conceptually. Think about your design and task of the function first - is "
"it a function that must not change object internal state?", true);
}
void CheckClass::checkConstError2(const Token *tok1, const Token *tok2, const std::string &classname, const std::string &funcname)
@ -1439,13 +1439,13 @@ void CheckClass::checkConstError2(const Token *tok1, const Token *tok2, const st
std::list<const Token *> toks;
toks.push_back(tok1);
toks.push_back(tok2);
reportInconclusiveError(toks, Severity::style, "functionConst",
"Technically the member function '" + classname + "::" + funcname + "' can be const.\n"
"The member function '" + classname + "::" + funcname + "' can be made a const "
"function. Making this function const function should not cause compiler errors. "
"Even though the function can be made const function technically it may not make "
"sense conceptually. Think about your design and task of the function first - is "
"it a function that must not change object internal state?");
reportError(toks, Severity::style, "functionConst",
"Technically the member function '" + classname + "::" + funcname + "' can be const.\n"
"The member function '" + classname + "::" + funcname + "' can be made a const "
"function. Making this function const function should not cause compiler errors. "
"Even though the function can be made const function technically it may not make "
"sense conceptually. Think about your design and task of the function first - is "
"it a function that must not change object internal state?", true);
}
//---------------------------------------------------------------------------
@ -1527,11 +1527,11 @@ void CheckClass::initializerListError(const Token *tok1, const Token *tok2, cons
std::list<const Token *> toks;
toks.push_back(tok1);
toks.push_back(tok2);
reportInconclusiveError(toks, Severity::style, "initializerList",
"Member variable '" + classname + "::" +
varname + "' is in the wrong order in the initializer list.\n"
"Members are initialized in the order they are declared, not the "
"order they are in the initializer list. Keeping the initializer list "
"in the same order that the members were declared prevents order dependent "
"initialization errors.");
reportError(toks, Severity::style, "initializerList",
"Member variable '" + classname + "::" +
varname + "' is in the wrong order in the initializer list.\n"
"Members are initialized in the order they are declared, not the "
"order they are in the initializer list. Keeping the initializer list "
"in the same order that the members were declared prevents order dependent "
"initialization errors.", true);
}

View File

@ -1421,8 +1421,5 @@ void CheckNullPointer::nullPointerError(const Token *tok, const std::string &var
void CheckNullPointer::nullPointerError(const Token *tok, const std::string &varname, const unsigned int line, bool inconclusive)
{
const std::string errmsg("Possible null pointer dereference: " + varname + " - otherwise it is redundant to check if " + varname + " is null at line " + MathLib::toString<unsigned int>(line));
if (inconclusive)
reportInconclusiveError(tok, Severity::error, "nullPointer", errmsg);
else
reportError(tok, Severity::error, "nullPointer", errmsg);
reportError(tok, Severity::error, "nullPointer", errmsg, inconclusive);
}

View File

@ -259,8 +259,8 @@ void CheckOther::checkBitwiseOnBoolean()
void CheckOther::bitwiseOnBooleanError(const Token *tok, const std::string &varname, const std::string &op)
{
reportInconclusiveError(tok, Severity::style, "bitwiseOnBoolean",
"Boolean variable '" + varname + "' is used in bitwise operation. Did you mean " + op + " ?");
reportError(tok, Severity::style, "bitwiseOnBoolean",
"Boolean variable '" + varname + "' is used in bitwise operation. Did you mean " + op + " ?", true);
}
void CheckOther::checkSuspiciousSemicolon()
@ -291,8 +291,8 @@ void CheckOther::checkSuspiciousSemicolon()
void CheckOther::SuspiciousSemicolonError(const Token* tok)
{
reportInconclusiveError(tok, Severity::warning, "suspiciousSemicolon",
"Suspicious use of ; at the end of 'if/for/while' statement.");
reportError(tok, Severity::warning, "suspiciousSemicolon",
"Suspicious use of ; at the end of 'if/for/while' statement.", true);
}
@ -418,7 +418,7 @@ void CheckOther::invalidPointerCastError(const Token* tok, const std::string& fr
if (!inconclusive)
reportError(tok, Severity::portability, "invalidPointerCast", "Casting from " + from + "* to integer* is not portable due to different binary data representations on different platforms");
else
reportInconclusiveError(tok, Severity::portability, "invalidPointerCast", "Casting from " + from + "* to char* might be not portable due to different binary data representations on different platforms");
reportError(tok, Severity::portability, "invalidPointerCast", "Casting from " + from + "* to char* might be not portable due to different binary data representations on different platforms", true);
} else
reportError(tok, Severity::warning, "invalidPointerCast", "Casting between " + from + "* and " + to + "* which have an incompatible binary data representation");
}
@ -613,11 +613,11 @@ void CheckOther::checkSizeofForPointerSize()
void CheckOther::sizeofForPointerError(const Token *tok, const std::string &varname)
{
reportInconclusiveError(tok, Severity::warning, "pointerSize",
"Using size of pointer " + varname + " instead of size of its data.\n"
"Using size of pointer " + varname + " instead of size of its data. "
"This is likely to lead to a buffer overflow. You probably intend to "
"write sizeof(*" + varname + ")");
reportError(tok, Severity::warning, "pointerSize",
"Using size of pointer " + varname + " instead of size of its data.\n"
"Using size of pointer " + varname + " instead of size of its data. "
"This is likely to lead to a buffer overflow. You probably intend to "
"write sizeof(*" + varname + ")", true);
}
//---------------------------------------------------------------------------
@ -1810,24 +1810,15 @@ void CheckOther::checkUnreachableCode()
void CheckOther::duplicateBreakError(const Token *tok, bool inconclusive)
{
if (inconclusive)
reportInconclusiveError(tok, Severity::style, "duplicateBreak",
"Consecutive return, break, continue, goto or throw statements are unnecessary.\n"
"The second of the two statements can never be executed, and so should be removed.");
else
reportError(tok, Severity::style, "duplicateBreak",
"Consecutive return, break, continue, goto or throw statements are unnecessary.\n"
"The second of the two statements can never be executed, and so should be removed.");
reportError(tok, Severity::style, "duplicateBreak",
"Consecutive return, break, continue, goto or throw statements are unnecessary.\n"
"The second of the two statements can never be executed, and so should be removed.", inconclusive);
}
void CheckOther::unreachableCodeError(const Token *tok, bool inconclusive)
{
if (inconclusive)
reportInconclusiveError(tok, Severity::style, "unreachableCode",
"Statements following return, break, continue, goto or throw will never be executed.");
else
reportError(tok, Severity::style, "unreachableCode",
"Statements following return, break, continue, goto or throw will never be executed.");
reportError(tok, Severity::style, "unreachableCode",
"Statements following return, break, continue, goto or throw will never be executed.", inconclusive);
}
//---------------------------------------------------------------------------
@ -1877,7 +1868,7 @@ void CheckOther::checkUnsignedDivision()
void CheckOther::udivError(const Token *tok, bool inconclusive)
{
if (inconclusive)
reportInconclusiveError(tok, Severity::warning, "udivError", "Division with signed and unsigned operators. The result might be wrong.");
reportError(tok, Severity::warning, "udivError", "Division with signed and unsigned operators. The result might be wrong.", true);
else
reportError(tok, Severity::error, "udivError", "Unsigned division. The result will be wrong.");
}
@ -3206,12 +3197,8 @@ void CheckOther::sizeofCalculation()
void CheckOther::sizeofCalculationError(const Token *tok, bool inconclusive)
{
if (inconclusive)
reportInconclusiveError(tok, Severity::warning,
"sizeofCalculation", "Found calculation inside sizeof()");
else
reportError(tok, Severity::warning,
"sizeofCalculation", "Found calculation inside sizeof()");
reportError(tok, Severity::warning,
"sizeofCalculation", "Found calculation inside sizeof()", inconclusive);
}
//-----------------------------------------------------------------------------
@ -3342,12 +3329,12 @@ void CheckOther::checkSignOfUnsignedVariable()
void CheckOther::unsignedLessThanZeroError(const Token *tok, const std::string &varname, bool inconclusive)
{
if (inconclusive) {
reportInconclusiveError(tok, Severity::style, "unsignedLessThanZero",
"Checking if unsigned variable '" + varname + "' is less than zero. This might be a false warning.\n"
"Checking if unsigned variable '" + varname + "' is less than zero. An unsigned "
"variable will never be negative so it is either pointless or an error to check if it is. "
"It's not known if the used constant is a template parameter or not and therefore "
"this message might be a false warning");
reportError(tok, Severity::style, "unsignedLessThanZero",
"Checking if unsigned variable '" + varname + "' is less than zero. This might be a false warning.\n"
"Checking if unsigned variable '" + varname + "' is less than zero. An unsigned "
"variable will never be negative so it is either pointless or an error to check if it is. "
"It's not known if the used constant is a template parameter or not and therefore "
"this message might be a false warning", true);
} else {
reportError(tok, Severity::style, "unsignedLessThanZero",
"Checking if unsigned variable '" + varname + "' is less than zero.\n"
@ -3359,11 +3346,11 @@ void CheckOther::unsignedLessThanZeroError(const Token *tok, const std::string &
void CheckOther::unsignedPositiveError(const Token *tok, const std::string &varname, bool inconclusive)
{
if (inconclusive) {
reportInconclusiveError(tok, Severity::style, "unsignedPositive",
"An unsigned variable '" + varname + "' can't be negative so it is unnecessary to test it. This might be a false warning.\n"
"An unsigned variable '" + varname + "' can't be negative so it is unnecessary to test it. "
"It's not known if the used constant is a "
"template parameter or not and therefore this message might be a false warning");
reportError(tok, Severity::style, "unsignedPositive",
"An unsigned variable '" + varname + "' can't be negative so it is unnecessary to test it. This might be a false warning.\n"
"An unsigned variable '" + varname + "' can't be negative so it is unnecessary to test it. "
"It's not known if the used constant is a "
"template parameter or not and therefore this message might be a false warning", true);
} else {
reportError(tok, Severity::style, "unsignedPositive",
"An unsigned variable '" + varname + "' can't be negative so it is unnecessary to test it.");

View File

@ -285,8 +285,12 @@ std::string ErrorLogger::ErrorMessage::toString(bool verbose, const std::string
std::ostringstream text;
if (!_callStack.empty())
text << callStackToString(_callStack) << ": ";
if (_severity != Severity::none)
text << '(' << Severity::toString(_severity) << ") ";
if (_severity != Severity::none) {
text << '(' << Severity::toString(_severity);
if (_inconclusive)
text << ", inconclusive";
text << ") ";
}
text << (verbose ? _verboseMessage : _shortMessage);
return text.str();
}

View File

@ -186,7 +186,7 @@ private:
" char a;\n"
" ab->a = &a;\n"
"}", true);
ASSERT_EQUALS("[test.cpp:4]: (error) Inconclusive: Assigning address of local auto-variable to a function parameter.\n", errout.str());
ASSERT_EQUALS("[test.cpp:4]: (error, inconclusive) Assigning address of local auto-variable to a function parameter.\n", errout.str());
}
void testautovar6() { // ticket #2931
@ -202,7 +202,7 @@ private:
" char a[10];\n"
" x->str = a;\n"
"}", true);
ASSERT_EQUALS("[test.cpp:4]: (error) Inconclusive: Assigning address of local auto-variable to a function parameter.\n", errout.str());
ASSERT_EQUALS("[test.cpp:4]: (error, inconclusive) Assigning address of local auto-variable to a function parameter.\n", errout.str());
}
void testautovar7() { // ticket #3066

View File

@ -3165,7 +3165,7 @@ private:
" char c[6];\n"
" strncpy(c,\"hello!\",sizeof(c));\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (warning) The buffer 'c' is not zero-terminated after the call to strncpy().\n", errout.str());
ASSERT_EQUALS("[test.cpp:4]: (warning, inconclusive) The buffer 'c' is not zero-terminated after the call to strncpy().\n", errout.str());
check("void f()\n"
"{\n"
@ -3565,21 +3565,21 @@ private:
" char c[6];\n"
" strncpy(c,\"hello!\",sizeof(c));\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (warning) The buffer 'c' is not zero-terminated after the call to strncpy().\n", errout.str());
ASSERT_EQUALS("[test.cpp:4]: (warning, inconclusive) The buffer 'c' is not zero-terminated after the call to strncpy().\n", errout.str());
check("void f()\n"
"{\n"
" char c[6];\n"
" memcpy(c,\"hello!\",sizeof(c));\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (warning) The buffer 'c' is not zero-terminated after the call to memcpy().\n", errout.str());
ASSERT_EQUALS("[test.cpp:4]: (warning, inconclusive) The buffer 'c' is not zero-terminated after the call to memcpy().\n", errout.str());
check("void f()\n"
"{\n"
" char c[6];\n"
" memmove(c,\"hello!\",sizeof(c));\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (warning) The buffer 'c' is not zero-terminated after the call to memmove().\n", errout.str());
ASSERT_EQUALS("[test.cpp:4]: (warning, inconclusive) The buffer 'c' is not zero-terminated after the call to memmove().\n", errout.str());
}
void readlink() {
@ -3589,7 +3589,7 @@ private:
" ssize_t len = readlink(path, buf, sizeof(buf)-1);\n"
" printf(\"%s\n\", buf);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (warning) The buffer 'buf' is not zero-terminated after the call to readlink().\n", errout.str());
ASSERT_EQUALS("[test.cpp:4]: (warning, inconclusive) The buffer 'buf' is not zero-terminated after the call to readlink().\n", errout.str());
// C only: Primitive pointer simplification
check("void f()\n"
@ -3598,7 +3598,7 @@ private:
" ssize_t len = readlink(path, &buf[0], sizeof(buf)-1);\n"
" printf(\"%s\n\", buf);\n"
"}\n", true, "test.c");
ASSERT_EQUALS("[test.c:4]: (warning) The buffer 'buf' is not zero-terminated after the call to readlink().\n", errout.str());
ASSERT_EQUALS("[test.c:4]: (warning, inconclusive) The buffer 'buf' is not zero-terminated after the call to readlink().\n", errout.str());
check("void f()\n"
"{\n"
@ -3622,7 +3622,7 @@ private:
" ssize_t len = readlink(path, buf, sizeof(buf));\n"
" buf[len] = 0;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (warning) readlink() might return the full size of 'buf'. Lower the supplied size by one.\n", errout.str());
ASSERT_EQUALS("[test.cpp:4]: (warning, inconclusive) readlink() might return the full size of 'buf'. Lower the supplied size by one.\n", errout.str());
check("void f()\n"
"{\n"
@ -3644,7 +3644,7 @@ private:
" ssize_t len = readlinkat(dirfd, path, buf, sizeof(buf)-1);\n"
" printf(\"%s\n\", buf);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:5]: (warning) The buffer 'buf' is not zero-terminated after the call to readlinkat().\n", errout.str());
ASSERT_EQUALS("[test.cpp:5]: (warning, inconclusive) The buffer 'buf' is not zero-terminated after the call to readlinkat().\n", errout.str());
check("void f()\n"
"{\n"
@ -3671,7 +3671,7 @@ private:
" ssize_t len = readlinkat(dirfd, path, buf, sizeof(buf));\n"
" buf[len] = 0;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:5]: (warning) readlinkat() might return the full size of 'buf'. Lower the supplied size by one.\n", errout.str());
ASSERT_EQUALS("[test.cpp:5]: (warning, inconclusive) readlinkat() might return the full size of 'buf'. Lower the supplied size by one.\n", errout.str());
check("void f()\n"
"{\n"

File diff suppressed because it is too large Load Diff

View File

@ -79,7 +79,7 @@ private:
" unsigned int uvar = 2;\n"
" return ivar / uvar;\n"
"}", true);
ASSERT_EQUALS("[test.cpp:5]: (warning) Division with signed and unsigned operators. The result might be wrong.\n", errout.str());
ASSERT_EQUALS("[test.cpp:5]: (warning, inconclusive) Division with signed and unsigned operators. The result might be wrong.\n", errout.str());
}
void division2() {
@ -89,7 +89,7 @@ private:
" unsigned int uvar = 2;\n"
" return uvar / ivar;\n"
"}", true);
ASSERT_EQUALS("[test.cpp:5]: (warning) Division with signed and unsigned operators. The result might be wrong.\n", errout.str());
ASSERT_EQUALS("[test.cpp:5]: (warning, inconclusive) Division with signed and unsigned operators. The result might be wrong.\n", errout.str());
}
void division4() {
@ -182,7 +182,7 @@ private:
" unsigned long uvar = 2;\n"
" return ivar / uvar;\n"
"}", true);
ASSERT_EQUALS("[test.cpp:5]: (warning) Division with signed and unsigned operators. The result might be wrong.\n", errout.str());
ASSERT_EQUALS("[test.cpp:5]: (warning, inconclusive) Division with signed and unsigned operators. The result might be wrong.\n", errout.str());
check("void f()\n"
"{\n"
@ -190,7 +190,7 @@ private:
" unsigned long long uvar = 2;\n"
" return ivar / uvar;\n"
"}", true);
ASSERT_EQUALS("[test.cpp:5]: (warning) Division with signed and unsigned operators. The result might be wrong.\n", errout.str());
ASSERT_EQUALS("[test.cpp:5]: (warning, inconclusive) Division with signed and unsigned operators. The result might be wrong.\n", errout.str());
}
void division10() {

View File

@ -118,7 +118,7 @@ private:
ASSERT_EQUALS("", errout.str());
check(code, true); // inconclusive=true => error
ASSERT_EQUALS("[test.cpp:6]: (error) Possible null pointer dereference: tok - otherwise it is redundant to check if tok is null at line 3\n", errout.str());
ASSERT_EQUALS("[test.cpp:6]: (error, inconclusive) Possible null pointer dereference: tok - otherwise it is redundant to check if tok is null at line 3\n", errout.str());
}
check("void foo()\n"
@ -190,7 +190,7 @@ private:
ASSERT_EQUALS("", errout.str());
check(code, true);
ASSERT_EQUALS("[test.cpp:5]: (error) Possible null pointer dereference: tok - otherwise it is redundant to check if tok is null at line 3\n", errout.str());
ASSERT_EQUALS("[test.cpp:5]: (error, inconclusive) Possible null pointer dereference: tok - otherwise it is redundant to check if tok is null at line 3\n", errout.str());
}
check("int foo(const Token *tok)\n"
@ -462,7 +462,7 @@ private:
check(code);
ASSERT_EQUALS("", errout.str());
check(code, true);
ASSERT_EQUALS("[test.cpp:2]: (error) Possible null pointer dereference: fred - otherwise it is redundant to check if fred is null at line 3\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (error, inconclusive) Possible null pointer dereference: fred - otherwise it is redundant to check if fred is null at line 3\n", errout.str());
}
// false positives when there are macros
@ -1338,7 +1338,7 @@ private:
" }\n"
" *p = 0;\n"
"}\n", true);
ASSERT_EQUALS("[test.cpp:5]: (error) Possible null pointer dereference: p - otherwise it is redundant to check if p is null at line 2\n", errout.str());
ASSERT_EQUALS("[test.cpp:5]: (error, inconclusive) Possible null pointer dereference: p - otherwise it is redundant to check if p is null at line 2\n", errout.str());
check("void foo(char *p) {\n"
" if (!p) {\n"
@ -1599,7 +1599,7 @@ private:
ASSERT_EQUALS("", errout.str());
check(code, true); // inconclusive
ASSERT_EQUALS("[test.cpp:3]: (error) Possible null pointer dereference: fred - otherwise it is redundant to check if fred is null at line 2\n", errout.str());
ASSERT_EQUALS("[test.cpp:3]: (error, inconclusive) Possible null pointer dereference: fred - otherwise it is redundant to check if fred is null at line 2\n", errout.str());
}
check("void f(char *s) {\n" // #3358
@ -2029,7 +2029,7 @@ private:
" foo(p);\n"
" if (p) { }\n"
"}", true);
ASSERT_EQUALS("[test.cpp:2]: (error) Possible null pointer dereference: p - otherwise it is redundant to check if p is null at line 4\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (error, inconclusive) Possible null pointer dereference: p - otherwise it is redundant to check if p is null at line 4\n", errout.str());
}
// dereference struct pointer and then check if it's null
@ -2068,7 +2068,7 @@ private:
" foo(abc);\n"
" if (abc) { }\n"
"}", true);
ASSERT_EQUALS("[test.cpp:2]: (error) Possible null pointer dereference: abc - otherwise it is redundant to check if abc is null at line 4\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (error, inconclusive) Possible null pointer dereference: abc - otherwise it is redundant to check if abc is null at line 4\n", errout.str());
}
}

View File

@ -854,15 +854,15 @@ private:
"}");
ASSERT_EQUALS("[test.cpp:2]: (warning) Casting between double* and float* which have an incompatible binary data representation\n", errout.str());
checkInvalidPointerCast("void test(float* data) {\n" // #3639
checkInvalidPointerCast("void test(float* data) {\n"
" f.write((char*)data,sizeof(float));\n"
"}", true, false);
ASSERT_EQUALS("", errout.str());
checkInvalidPointerCast("void test(float* data) {\n"
" f.write((char*)data,sizeof(float));\n"
"}", true, true);
ASSERT_EQUALS("[test.cpp:2]: (portability) Casting from float* to char* might be not portable due to different binary data representations on different platforms\n", errout.str());
"}", true, true); // #3639
ASSERT_EQUALS("[test.cpp:2]: (portability, inconclusive) Casting from float* to char* might be not portable due to different binary data representations on different platforms\n", errout.str());
checkInvalidPointerCast("long long* test(float* f) {\n"
@ -2062,7 +2062,7 @@ private:
"\n" // #endif
" return 1;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary.\n", errout.str());
ASSERT_EQUALS("[test.cpp:5]: (style, inconclusive) Consecutive return, break, continue, goto or throw statements are unnecessary.\n", errout.str());
}
@ -3598,71 +3598,71 @@ private:
check("void f(_Bool a, _Bool b) {\n"
" if(a & b) {}\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Boolean variable 'a' is used in bitwise operation. Did you mean && ?\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (style, inconclusive) Boolean variable 'a' is used in bitwise operation. Did you mean && ?\n", errout.str());
check("void f(_Bool a, _Bool b) {\n"
" if(a | b) {}\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Boolean variable 'a' is used in bitwise operation. Did you mean || ?\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (style, inconclusive) Boolean variable 'a' is used in bitwise operation. Did you mean || ?\n", errout.str());
check("void f(bool a, bool b) {\n"
" if(a & b) {}\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Boolean variable 'a' is used in bitwise operation. Did you mean && ?\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (style, inconclusive) Boolean variable 'a' is used in bitwise operation. Did you mean && ?\n", errout.str());
check("void f(bool a, bool b) {\n"
" if(a & !b) {}\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Boolean variable 'a' is used in bitwise operation. Did you mean && ?\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (style, inconclusive) Boolean variable 'a' is used in bitwise operation. Did you mean && ?\n", errout.str());
check("void f(bool a, bool b) {\n"
" if(a | b) {}\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Boolean variable 'a' is used in bitwise operation. Did you mean || ?\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (style, inconclusive) Boolean variable 'a' is used in bitwise operation. Did you mean || ?\n", errout.str());
check("void f(bool a, bool b) {\n"
" if(a | !b) {}\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Boolean variable 'a' is used in bitwise operation. Did you mean || ?\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (style, inconclusive) Boolean variable 'a' is used in bitwise operation. Did you mean || ?\n", errout.str());
check("bool a, b;\n"
"void f() {\n"
" if(a & b) {}\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Boolean variable 'a' is used in bitwise operation. Did you mean && ?\n", errout.str());
ASSERT_EQUALS("[test.cpp:3]: (style, inconclusive) Boolean variable 'a' is used in bitwise operation. Did you mean && ?\n", errout.str());
check("bool a, b;\n"
"void f() {\n"
" if(a & !b) {}\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Boolean variable 'a' is used in bitwise operation. Did you mean && ?\n", errout.str());
ASSERT_EQUALS("[test.cpp:3]: (style, inconclusive) Boolean variable 'a' is used in bitwise operation. Did you mean && ?\n", errout.str());
check("bool a, b;\n"
"void f() {\n"
" if(a | b) {}\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Boolean variable 'a' is used in bitwise operation. Did you mean || ?\n", errout.str());
ASSERT_EQUALS("[test.cpp:3]: (style, inconclusive) Boolean variable 'a' is used in bitwise operation. Did you mean || ?\n", errout.str());
check("bool a, b;\n"
"void f() {\n"
" if(a | !b) {}\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Boolean variable 'a' is used in bitwise operation. Did you mean || ?\n", errout.str());
ASSERT_EQUALS("[test.cpp:3]: (style, inconclusive) Boolean variable 'a' is used in bitwise operation. Did you mean || ?\n", errout.str());
check("void f(bool a, int b) {\n"
" if(a & b) {}\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Boolean variable 'a' is used in bitwise operation. Did you mean && ?\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (style, inconclusive) Boolean variable 'a' is used in bitwise operation. Did you mean && ?\n", errout.str());
check("void f(int a, bool b) {\n"
" if(a & b) {}\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Boolean variable 'b' is used in bitwise operation. Did you mean && ?\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (style, inconclusive) Boolean variable 'b' is used in bitwise operation. Did you mean && ?\n", errout.str());
check("void f(bool a, bool b) {\n"
" if(a & b) {}\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Boolean variable 'a' is used in bitwise operation. Did you mean && ?\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (style, inconclusive) Boolean variable 'a' is used in bitwise operation. Did you mean && ?\n", errout.str());
check("void f(int a, int b) {\n"
" if(a & b) {}\n"
@ -4293,17 +4293,17 @@ private:
check(
"int *x = malloc(sizeof(x));\n"
"free(x);");
ASSERT_EQUALS("[test.cpp:1]: (warning) Using size of pointer x instead of size of its data.\n", errout.str());
ASSERT_EQUALS("[test.cpp:1]: (warning, inconclusive) Using size of pointer x instead of size of its data.\n", errout.str());
check(
"int *x = malloc(100 * sizeof(x));\n"
"free(x);");
ASSERT_EQUALS("[test.cpp:1]: (warning) Using size of pointer x instead of size of its data.\n", errout.str());
ASSERT_EQUALS("[test.cpp:1]: (warning, inconclusive) Using size of pointer x instead of size of its data.\n", errout.str());
check(
"int *x = malloc(sizeof(x) * 100);\n"
"free(x);");
ASSERT_EQUALS("[test.cpp:1]: (warning) Using size of pointer x instead of size of its data.\n", errout.str());
ASSERT_EQUALS("[test.cpp:1]: (warning, inconclusive) Using size of pointer x instead of size of its data.\n", errout.str());
check(
"int *x = malloc(sizeof *x);\n"
@ -4313,12 +4313,12 @@ private:
check(
"int *x = malloc(sizeof x);\n"
"free(x);");
ASSERT_EQUALS("[test.cpp:1]: (warning) Using size of pointer x instead of size of its data.\n", errout.str());
ASSERT_EQUALS("[test.cpp:1]: (warning, inconclusive) Using size of pointer x instead of size of its data.\n", errout.str());
check(
"int *x = malloc(100 * sizeof x);\n"
"free(x);");
ASSERT_EQUALS("[test.cpp:1]: (warning) Using size of pointer x instead of size of its data.\n", errout.str());
ASSERT_EQUALS("[test.cpp:1]: (warning, inconclusive) Using size of pointer x instead of size of its data.\n", errout.str());
check(
"int *x = calloc(1, sizeof(*x));\n"
@ -4333,12 +4333,12 @@ private:
check(
"int *x = calloc(1, sizeof(x));\n"
"free(x);");
ASSERT_EQUALS("[test.cpp:1]: (warning) Using size of pointer x instead of size of its data.\n", errout.str());
ASSERT_EQUALS("[test.cpp:1]: (warning, inconclusive) Using size of pointer x instead of size of its data.\n", errout.str());
check(
"int *x = calloc(1, sizeof x);\n"
"free(x);");
ASSERT_EQUALS("[test.cpp:1]: (warning) Using size of pointer x instead of size of its data.\n", errout.str());
ASSERT_EQUALS("[test.cpp:1]: (warning, inconclusive) Using size of pointer x instead of size of its data.\n", errout.str());
check(
"int *x = calloc(1, sizeof(int));\n"
@ -4382,25 +4382,25 @@ private:
"int *x = malloc(sizeof(int));\n"
"memset(x, 0, sizeof x);\n"
"free(x);");
ASSERT_EQUALS("[test.cpp:2]: (warning) Using size of pointer x instead of size of its data.\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Using size of pointer x instead of size of its data.\n", errout.str());
check(
"int *x = malloc(sizeof(int));\n"
"memset(x, 0, sizeof(x));\n"
"free(x);");
ASSERT_EQUALS("[test.cpp:2]: (warning) Using size of pointer x instead of size of its data.\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Using size of pointer x instead of size of its data.\n", errout.str());
check(
"int *x = malloc(sizeof(int) * 10);\n"
"memset(x, 0, sizeof(x) * 10);\n"
"free(x);");
ASSERT_EQUALS("[test.cpp:2]: (warning) Using size of pointer x instead of size of its data.\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Using size of pointer x instead of size of its data.\n", errout.str());
check(
"int *x = malloc(sizeof(int) * 10);\n"
"memset(x, 0, sizeof x * 10);\n"
"free(x);");
ASSERT_EQUALS("[test.cpp:2]: (warning) Using size of pointer x instead of size of its data.\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Using size of pointer x instead of size of its data.\n", errout.str());
check(
"int *x = malloc(sizeof(int) * 10);\n"
@ -4426,13 +4426,13 @@ private:
" const char *buf1_ex = \"foobarbaz\";\n"
" return strncmp(buf1, buf1_ex, sizeof(buf1_ex)) == 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (warning) Using size of pointer buf1_ex instead of size of its data.\n", errout.str());
ASSERT_EQUALS("[test.cpp:4]: (warning, inconclusive) Using size of pointer buf1_ex instead of size of its data.\n", errout.str());
check(
"int fun(const char *buf1) {\n"
" return strncmp(buf1, foo(buf2), sizeof(buf1)) == 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (warning) Using size of pointer buf1 instead of size of its data.\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Using size of pointer buf1 instead of size of its data.\n", errout.str());
}
void check_signOfUnsignedVariable(const char code[], bool inconclusive=false) {
@ -4673,7 +4673,7 @@ private:
check_signOfUnsignedVariable(code, false);
ASSERT_EQUALS("", errout.str());
check_signOfUnsignedVariable(code, true);
ASSERT_EQUALS("[test.cpp:2]: (style) Checking if unsigned variable 'x' is less than zero. This might be a false warning.\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (style, inconclusive) Checking if unsigned variable 'x' is less than zero. This might be a false warning.\n", errout.str());
}
}
@ -4690,7 +4690,7 @@ private:
" for(int i = 0; i < 10; ++i); {\n"
" }\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (warning) Suspicious use of ; at the end of 'if/for/while' statement.\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Suspicious use of ; at the end of 'if/for/while' statement.\n", errout.str());
// Block with some tokens to make sure the tokenizer output
// stays the same for "for(); {}"
@ -4700,7 +4700,7 @@ private:
" int j = 123;\n"
" }\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (warning) Suspicious use of ; at the end of 'if/for/while' statement.\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Suspicious use of ; at the end of 'if/for/while' statement.\n", errout.str());
check(
"void foo() {\n"
@ -4708,7 +4708,7 @@ private:
" do_something();\n"
" }\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (warning) Suspicious use of ; at the end of 'if/for/while' statement.\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Suspicious use of ; at the end of 'if/for/while' statement.\n", errout.str());
}
void checkForSuspiciousSemicolon2() {
@ -4718,7 +4718,7 @@ private:
" do_something();\n"
" }\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (warning) Suspicious use of ; at the end of 'if/for/while' statement.\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Suspicious use of ; at the end of 'if/for/while' statement.\n", errout.str());
// Seen this in the wild
check(

View File

@ -4385,10 +4385,10 @@ private:
ASSERT_EQUALS(expected, tok(code, false));
checkSimplifyTypedef(code);
ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:1]: (style) The typedef 'A' hides a typedef with the same name.\n"
"[test.cpp:20] -> [test.cpp:1]: (style) The function parameter 'A' hides a typedef with the same name.\n"
"[test.cpp:21] -> [test.cpp:1]: (style) The variable 'A' hides a typedef with the same name.\n"
"[test.cpp:24] -> [test.cpp:1]: (style) The typedef 'A' hides a typedef with the same name.\n", errout.str());
ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:1]: (style, inconclusive) The typedef 'A' hides a typedef with the same name.\n"
"[test.cpp:20] -> [test.cpp:1]: (style, inconclusive) The function parameter 'A' hides a typedef with the same name.\n"
"[test.cpp:21] -> [test.cpp:1]: (style, inconclusive) The variable 'A' hides a typedef with the same name.\n"
"[test.cpp:24] -> [test.cpp:1]: (style, inconclusive) The typedef 'A' hides a typedef with the same name.\n", errout.str());
}
void simplifyTypedef36() {
@ -4415,8 +4415,8 @@ private:
"typedef int B;";
checkSimplifyTypedef(code);
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:2]: (style) The typedef 'A' hides a typedef with the same name.\n"
"[test.cpp:5] -> [test.cpp:3]: (style) The typedef 'B' hides a typedef with the same name.\n", errout.str());
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:2]: (style, inconclusive) The typedef 'A' hides a typedef with the same name.\n"
"[test.cpp:5] -> [test.cpp:3]: (style, inconclusive) The typedef 'B' hides a typedef with the same name.\n", errout.str());
}
{
@ -4461,8 +4461,8 @@ private:
ASSERT_EQUALS(expected, tok(code, false));
checkSimplifyTypedef(code);
ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:1]: (style) The template parameter 'A' hides a typedef with the same name.\n"
"[test.cpp:3] -> [test.cpp:2]: (style) The template parameter 'B' hides a typedef with the same name.\n", errout.str());
ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:1]: (style, inconclusive) The template parameter 'A' hides a typedef with the same name.\n"
"[test.cpp:3] -> [test.cpp:2]: (style, inconclusive) The template parameter 'B' hides a typedef with the same name.\n", errout.str());
checkSimplifyTypedef("typedef tuple<double&, const double&, const double, double*, const double*> t2;\n"
"void ordering_test()\n"
@ -4470,7 +4470,7 @@ private:
" tuple<short, float> t2(5, 3.3f);\n"
" BOOST_CHECK(t3 > t2);\n"
"}");
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:1]: (style) The template instantiation 't2' hides a typedef with the same name.\n", errout.str());
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:1]: (style, inconclusive) The template instantiation 't2' hides a typedef with the same name.\n", errout.str());
checkSimplifyTypedef("class MyOverflowingUnsigned\n"
"{\n"
@ -4551,7 +4551,7 @@ private:
ASSERT_EQUALS(expected, tok(code));
checkSimplifyTypedef(code);
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1]: (style) The struct 'A' hides a typedef with the same name.\n", errout.str());
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1]: (style, inconclusive) The struct 'A' hides a typedef with the same name.\n", errout.str());
}
{
@ -4569,7 +4569,7 @@ private:
ASSERT_EQUALS(expected, tok(code));
checkSimplifyTypedef(code);
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1]: (style) The union 'A' hides a typedef with the same name.\n", errout.str());
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1]: (style, inconclusive) The union 'A' hides a typedef with the same name.\n", errout.str());
}
{
@ -4587,7 +4587,7 @@ private:
ASSERT_EQUALS(expected, tok(code));
checkSimplifyTypedef(code);
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1]: (style) The class 'A' hides a typedef with the same name.\n", errout.str());
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1]: (style, inconclusive) The class 'A' hides a typedef with the same name.\n", errout.str());
}
}
@ -4816,14 +4816,14 @@ private:
"typedef int (*PPDMarkOption)(ppd_file_t *ppd, const char *keyword, const char *option);\n";
checkSimplifyTypedef(code);
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1]: (style) The typedef 'PPDMarkOption' hides a typedef with the same name.\n", errout.str());
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1]: (style, inconclusive) The typedef 'PPDMarkOption' hides a typedef with the same name.\n", errout.str());
}
{
const char code[] = "typedef int * A;\n"
"typedef int * A;\n";
checkSimplifyTypedef(code);
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1]: (style) The typedef 'A' hides a typedef with the same name.\n", errout.str());
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1]: (style, inconclusive) The typedef 'A' hides a typedef with the same name.\n", errout.str());
}
}