- 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; ErrorLogger * const _errorLogger;
/** report an error */ /** report an error */
void reportError(const Token *tok, const Severity::SeverityType severity, const std::string &id, const std::string &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; std::list<const Token *> callstack(1, tok);
if (tok) reportError(callstack, severity, id, msg, inconclusive);
callstack.push_back(tok);
reportError(callstack, severity, id, msg);
} }
/** report an error */ /** report an error */
void reportError(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string& msg) { void reportError(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string& msg, bool inconclusive = false) {
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) {
ErrorLogger::ErrorMessage errmsg(callstack, _tokenizer?&_tokenizer->list:0, severity, id, msg, inconclusive); ErrorLogger::ErrorMessage errmsg(callstack, _tokenizer?&_tokenizer->list:0, severity, id, msg, inconclusive);
if (_errorLogger) if (_errorLogger)
_errorLogger->reportErr(errmsg); _errorLogger->reportErr(errmsg);
@ -155,6 +128,11 @@ private:
reportError(errmsg); reportError(errmsg);
} }
private:
const std::string _name;
/** disabled assignment operator */
void operator=(const Check &);
}; };
namespace std { 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 " "stack is freed when the function ends. So the pointer to a local variable "
"is invalid after the function ends."); "is invalid after the function ends.");
} else { } else {
reportInconclusiveError(tok, Severity::error, "autoVariables", reportError(tok, Severity::error, "autoVariables",
"Inconclusive: Assigning address of local auto-variable to a function parameter.\n" "Assigning address of local auto-variable to a function parameter.\n"
"Inconclusive: function parameter takes the address of a local auto-variable. " "Function parameter takes the address of a local auto-variable. "
"Local auto-variables are reserved from the stack. And the stack is freed when " "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 " "the function ends. The address is invalid after the function ends and it "
"might 'leak' from the function through the parameter."); "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. " 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."; "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) 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 + "(). " "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."; "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) void CheckClass::checkConstError(const Token *tok, const std::string &classname, const std::string &funcname)
{ {
reportInconclusiveError(tok, Severity::style, "functionConst", reportError(tok, Severity::style, "functionConst",
"Technically the member function '" + classname + "::" + funcname + "' can be const.\n" "Technically the member function '" + classname + "::" + funcname + "' can be const.\n"
"The member function '" + classname + "::" + funcname + "' can be made a const " "The member function '" + classname + "::" + funcname + "' can be made a const "
"function. Making this function const function should not cause compiler errors. " "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 " "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 " "sense conceptually. Think about your design and task of the function first - is "
"it a function that must not change object internal state?"); "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) 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; std::list<const Token *> toks;
toks.push_back(tok1); toks.push_back(tok1);
toks.push_back(tok2); toks.push_back(tok2);
reportInconclusiveError(toks, Severity::style, "functionConst", reportError(toks, Severity::style, "functionConst",
"Technically the member function '" + classname + "::" + funcname + "' can be const.\n" "Technically the member function '" + classname + "::" + funcname + "' can be const.\n"
"The member function '" + classname + "::" + funcname + "' can be made a const " "The member function '" + classname + "::" + funcname + "' can be made a const "
"function. Making this function const function should not cause compiler errors. " "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 " "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 " "sense conceptually. Think about your design and task of the function first - is "
"it a function that must not change object internal state?"); "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; std::list<const Token *> toks;
toks.push_back(tok1); toks.push_back(tok1);
toks.push_back(tok2); toks.push_back(tok2);
reportInconclusiveError(toks, Severity::style, "initializerList", reportError(toks, Severity::style, "initializerList",
"Member variable '" + classname + "::" + "Member variable '" + classname + "::" +
varname + "' is in the wrong order in the initializer list.\n" varname + "' is in the wrong order in the initializer list.\n"
"Members are initialized in the order they are declared, not the " "Members are initialized in the order they are declared, not the "
"order they are in the initializer list. Keeping the initializer list " "order they are in the initializer list. Keeping the initializer list "
"in the same order that the members were declared prevents order dependent " "in the same order that the members were declared prevents order dependent "
"initialization errors."); "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) 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)); 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) reportError(tok, Severity::error, "nullPointer", errmsg, inconclusive);
reportInconclusiveError(tok, Severity::error, "nullPointer", errmsg);
else
reportError(tok, Severity::error, "nullPointer", errmsg);
} }

View File

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

View File

@ -186,7 +186,7 @@ private:
" char a;\n" " char a;\n"
" ab->a = &a;\n" " ab->a = &a;\n"
"}", true); "}", 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 void testautovar6() { // ticket #2931
@ -202,7 +202,7 @@ private:
" char a[10];\n" " char a[10];\n"
" x->str = a;\n" " x->str = a;\n"
"}", true); "}", 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 void testautovar7() { // ticket #3066

View File

@ -3165,7 +3165,7 @@ private:
" char c[6];\n" " char c[6];\n"
" strncpy(c,\"hello!\",sizeof(c));\n" " strncpy(c,\"hello!\",sizeof(c));\n"
"}\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" check("void f()\n"
"{\n" "{\n"
@ -3565,21 +3565,21 @@ private:
" char c[6];\n" " char c[6];\n"
" strncpy(c,\"hello!\",sizeof(c));\n" " strncpy(c,\"hello!\",sizeof(c));\n"
"}\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" check("void f()\n"
"{\n" "{\n"
" char c[6];\n" " char c[6];\n"
" memcpy(c,\"hello!\",sizeof(c));\n" " memcpy(c,\"hello!\",sizeof(c));\n"
"}\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" check("void f()\n"
"{\n" "{\n"
" char c[6];\n" " char c[6];\n"
" memmove(c,\"hello!\",sizeof(c));\n" " memmove(c,\"hello!\",sizeof(c));\n"
"}\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() { void readlink() {
@ -3589,7 +3589,7 @@ private:
" ssize_t len = readlink(path, buf, sizeof(buf)-1);\n" " ssize_t len = readlink(path, buf, sizeof(buf)-1);\n"
" printf(\"%s\n\", buf);\n" " printf(\"%s\n\", buf);\n"
"}\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 // C only: Primitive pointer simplification
check("void f()\n" check("void f()\n"
@ -3598,7 +3598,7 @@ private:
" ssize_t len = readlink(path, &buf[0], sizeof(buf)-1);\n" " ssize_t len = readlink(path, &buf[0], sizeof(buf)-1);\n"
" printf(\"%s\n\", buf);\n" " printf(\"%s\n\", buf);\n"
"}\n", true, "test.c"); "}\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" check("void f()\n"
"{\n" "{\n"
@ -3622,7 +3622,7 @@ private:
" ssize_t len = readlink(path, buf, sizeof(buf));\n" " ssize_t len = readlink(path, buf, sizeof(buf));\n"
" buf[len] = 0;\n" " buf[len] = 0;\n"
"}\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" check("void f()\n"
"{\n" "{\n"
@ -3644,7 +3644,7 @@ private:
" ssize_t len = readlinkat(dirfd, path, buf, sizeof(buf)-1);\n" " ssize_t len = readlinkat(dirfd, path, buf, sizeof(buf)-1);\n"
" printf(\"%s\n\", buf);\n" " printf(\"%s\n\", buf);\n"
"}\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" check("void f()\n"
"{\n" "{\n"
@ -3671,7 +3671,7 @@ private:
" ssize_t len = readlinkat(dirfd, path, buf, sizeof(buf));\n" " ssize_t len = readlinkat(dirfd, path, buf, sizeof(buf));\n"
" buf[len] = 0;\n" " buf[len] = 0;\n"
"}\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" check("void f()\n"
"{\n" "{\n"

File diff suppressed because it is too large Load Diff

View File

@ -79,7 +79,7 @@ private:
" unsigned int uvar = 2;\n" " unsigned int uvar = 2;\n"
" return ivar / uvar;\n" " return ivar / uvar;\n"
"}", true); "}", 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() { void division2() {
@ -89,7 +89,7 @@ private:
" unsigned int uvar = 2;\n" " unsigned int uvar = 2;\n"
" return uvar / ivar;\n" " return uvar / ivar;\n"
"}", true); "}", 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() { void division4() {
@ -182,7 +182,7 @@ private:
" unsigned long uvar = 2;\n" " unsigned long uvar = 2;\n"
" return ivar / uvar;\n" " return ivar / uvar;\n"
"}", true); "}", 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" check("void f()\n"
"{\n" "{\n"
@ -190,7 +190,7 @@ private:
" unsigned long long uvar = 2;\n" " unsigned long long uvar = 2;\n"
" return ivar / uvar;\n" " return ivar / uvar;\n"
"}", true); "}", 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() { void division10() {

View File

@ -118,7 +118,7 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check(code, true); // inconclusive=true => error 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" check("void foo()\n"
@ -190,7 +190,7 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check(code, true); 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" check("int foo(const Token *tok)\n"
@ -462,7 +462,7 @@ private:
check(code); check(code);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check(code, true); 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 // false positives when there are macros
@ -1338,7 +1338,7 @@ private:
" }\n" " }\n"
" *p = 0;\n" " *p = 0;\n"
"}\n", true); "}\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" check("void foo(char *p) {\n"
" if (!p) {\n" " if (!p) {\n"
@ -1599,7 +1599,7 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check(code, true); // inconclusive 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 check("void f(char *s) {\n" // #3358
@ -2029,7 +2029,7 @@ private:
" foo(p);\n" " foo(p);\n"
" if (p) { }\n" " if (p) { }\n"
"}", true); "}", 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 // dereference struct pointer and then check if it's null
@ -2068,7 +2068,7 @@ private:
" foo(abc);\n" " foo(abc);\n"
" if (abc) { }\n" " if (abc) { }\n"
"}", true); "}", 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()); 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" " f.write((char*)data,sizeof(float));\n"
"}", true, false); "}", true, false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
checkInvalidPointerCast("void test(float* data) {\n" checkInvalidPointerCast("void test(float* data) {\n"
" f.write((char*)data,sizeof(float));\n" " f.write((char*)data,sizeof(float));\n"
"}", true, true); "}", true, true); // #3639
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()); 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" checkInvalidPointerCast("long long* test(float* f) {\n"
@ -2062,7 +2062,7 @@ private:
"\n" // #endif "\n" // #endif
" return 1;\n" " 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" check("void f(_Bool a, _Bool b) {\n"
" if(a & 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" check("void f(_Bool a, _Bool b) {\n"
" if(a | 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" check("void f(bool a, bool b) {\n"
" if(a & 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" check("void f(bool a, bool b) {\n"
" if(a & !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" check("void f(bool a, bool b) {\n"
" if(a | 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" check("void f(bool a, bool b) {\n"
" if(a | !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" check("bool a, b;\n"
"void f() {\n" "void f() {\n"
" if(a & b) {}\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" check("bool a, b;\n"
"void f() {\n" "void f() {\n"
" if(a & !b) {}\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" check("bool a, b;\n"
"void f() {\n" "void f() {\n"
" if(a | b) {}\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" check("bool a, b;\n"
"void f() {\n" "void f() {\n"
" if(a | !b) {}\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" check("void f(bool a, int b) {\n"
" if(a & 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" check("void f(int a, bool b) {\n"
" if(a & 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" check("void f(bool a, bool b) {\n"
" if(a & 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" check("void f(int a, int b) {\n"
" if(a & b) {}\n" " if(a & b) {}\n"
@ -4293,17 +4293,17 @@ private:
check( check(
"int *x = malloc(sizeof(x));\n" "int *x = malloc(sizeof(x));\n"
"free(x);"); "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( check(
"int *x = malloc(100 * sizeof(x));\n" "int *x = malloc(100 * sizeof(x));\n"
"free(x);"); "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( check(
"int *x = malloc(sizeof(x) * 100);\n" "int *x = malloc(sizeof(x) * 100);\n"
"free(x);"); "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( check(
"int *x = malloc(sizeof *x);\n" "int *x = malloc(sizeof *x);\n"
@ -4313,12 +4313,12 @@ private:
check( check(
"int *x = malloc(sizeof x);\n" "int *x = malloc(sizeof x);\n"
"free(x);"); "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( check(
"int *x = malloc(100 * sizeof x);\n" "int *x = malloc(100 * sizeof x);\n"
"free(x);"); "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( check(
"int *x = calloc(1, sizeof(*x));\n" "int *x = calloc(1, sizeof(*x));\n"
@ -4333,12 +4333,12 @@ private:
check( check(
"int *x = calloc(1, sizeof(x));\n" "int *x = calloc(1, sizeof(x));\n"
"free(x);"); "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( check(
"int *x = calloc(1, sizeof x);\n" "int *x = calloc(1, sizeof x);\n"
"free(x);"); "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( check(
"int *x = calloc(1, sizeof(int));\n" "int *x = calloc(1, sizeof(int));\n"
@ -4382,25 +4382,25 @@ private:
"int *x = malloc(sizeof(int));\n" "int *x = malloc(sizeof(int));\n"
"memset(x, 0, sizeof x);\n" "memset(x, 0, sizeof x);\n"
"free(x);"); "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( check(
"int *x = malloc(sizeof(int));\n" "int *x = malloc(sizeof(int));\n"
"memset(x, 0, sizeof(x));\n" "memset(x, 0, sizeof(x));\n"
"free(x);"); "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( check(
"int *x = malloc(sizeof(int) * 10);\n" "int *x = malloc(sizeof(int) * 10);\n"
"memset(x, 0, sizeof(x) * 10);\n" "memset(x, 0, sizeof(x) * 10);\n"
"free(x);"); "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( check(
"int *x = malloc(sizeof(int) * 10);\n" "int *x = malloc(sizeof(int) * 10);\n"
"memset(x, 0, sizeof x * 10);\n" "memset(x, 0, sizeof x * 10);\n"
"free(x);"); "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( check(
"int *x = malloc(sizeof(int) * 10);\n" "int *x = malloc(sizeof(int) * 10);\n"
@ -4426,13 +4426,13 @@ private:
" const char *buf1_ex = \"foobarbaz\";\n" " const char *buf1_ex = \"foobarbaz\";\n"
" return strncmp(buf1, buf1_ex, sizeof(buf1_ex)) == 0;\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( check(
"int fun(const char *buf1) {\n" "int fun(const char *buf1) {\n"
" return strncmp(buf1, foo(buf2), sizeof(buf1)) == 0;\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) { void check_signOfUnsignedVariable(const char code[], bool inconclusive=false) {
@ -4673,7 +4673,7 @@ private:
check_signOfUnsignedVariable(code, false); check_signOfUnsignedVariable(code, false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check_signOfUnsignedVariable(code, true); 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" " for(int i = 0; i < 10; ++i); {\n"
" }\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 // Block with some tokens to make sure the tokenizer output
// stays the same for "for(); {}" // stays the same for "for(); {}"
@ -4700,7 +4700,7 @@ private:
" int j = 123;\n" " int j = 123;\n"
" }\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( check(
"void foo() {\n" "void foo() {\n"
@ -4708,7 +4708,7 @@ private:
" do_something();\n" " do_something();\n"
" }\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() { void checkForSuspiciousSemicolon2() {
@ -4718,7 +4718,7 @@ private:
" do_something();\n" " do_something();\n"
" }\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 // Seen this in the wild
check( check(

View File

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