Use FwdAnalysis in UnusedVar. This is still work-in-progress. Merging to master branch so it can be tested.

This commit is contained in:
Daniel Marjamäki 2018-12-13 18:52:56 +01:00
parent 02e1637553
commit 0b4e08cac9
10 changed files with 396 additions and 133 deletions

View File

@ -1040,7 +1040,7 @@ bool isLikelyStreamRead(bool cpp, const Token *op)
static bool nonLocal(const Variable* var)
{
return !var || (!var->isLocal() && !var->isArgument()) || var->isStatic() || var->isReference();
return !var || (!var->isLocal() && !var->isArgument()) || var->isStatic() || var->isReference() || var->isExtern();
}
static bool hasFunctionCall(const Token *tok)
@ -1071,9 +1071,41 @@ struct FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const
return Result(Result::Type::BREAK, tok);
}
if (Token::Match(tok, "continue|return|throw|goto")) {
if (Token::simpleMatch(tok, "goto"))
return Result(Result::Type::BAILOUT);
if (tok->str() == "continue")
// TODO
return Result(Result::Type::BAILOUT);
if (Token::Match(tok, "return|throw")) {
// TODO: Handle these better
return Result(Result::Type::RETURN);
switch (mWhat) {
case What::Reassign:
return Result(Result::Type::RETURN);
case What::UnusedValue:
// Is expr variable used in expression?
{
bool read = false;
visitAstNodes(tok->astOperand1(),
[&](const Token *tok2) {
if (!local && Token::Match(tok2, "%name% ("))
read = true;
if (tok2->varId() && exprVarIds.find(tok2->varId()) != exprVarIds.end())
read = true;
return read ? ChildrenToVisit::done : ChildrenToVisit::op1_and_op2;
});
return Result(read ? Result::Type::READ : Result::Type::RETURN);
}
}
}
if (tok->str() == "}") {
Scope::ScopeType scopeType = tok->scope()->type;
if (scopeType == Scope::eWhile || scopeType == Scope::eFor || scopeType == Scope::eDo)
// TODO handle loops better
return Result(Result::Type::BAILOUT);
}
if (Token::simpleMatch(tok, "else {"))
@ -1088,6 +1120,10 @@ struct FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const
return Result(Result::Type::BAILOUT);
}
if (expr->isName() && Token::Match(tok, "%name% (") && tok->str().find("<") != std::string::npos && tok->str().find(expr->str()) != std::string::npos)
return Result(Result::Type::BAILOUT);
if (exprVarIds.find(tok->varId()) != exprVarIds.end()) {
const Token *parent = tok;
while (Token::Match(parent->astParent(), ".|::|["))
@ -1098,7 +1134,7 @@ struct FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const
return Result(Result::Type::BAILOUT);
}
if (hasOperand(parent->astParent()->astOperand2(), expr)) {
if (mReassign)
if (mWhat == What::Reassign)
return Result(Result::Type::READ);
continue;
}
@ -1113,6 +1149,9 @@ struct FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const
}
if (Token::Match(tok, ") {")) {
if (Token::simpleMatch(tok->link()->previous(), "switch ("))
// TODO: parse switch
return Result(Result::Type::BAILOUT);
const Result &result1 = checkRecursive(expr, tok->tokAt(2), tok->linkAt(1), exprVarIds, local);
if (result1.type == Result::Type::READ || result1.type == Result::Type::BAILOUT)
return result1;
@ -1133,6 +1172,53 @@ struct FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const
return Result(Result::Type::NONE);
}
bool FwdAnalysis::isGlobalData(const Token *expr) const
{
bool globalData = false;
visitAstNodes(expr,
[&](const Token *tok) {
if (tok->originalName() == "->") {
// TODO check if pointer points at local data
globalData = true;
return ChildrenToVisit::none;
} else if (Token::Match(tok, "[*[]") && tok->astOperand1() && tok->astOperand1()->variable()) {
// TODO check if pointer points at local data
const Variable *lhsvar = tok->astOperand1()->variable();
const ValueType *lhstype = tok->astOperand1()->valueType();
if (lhsvar->isPointer()) {
globalData = true;
return ChildrenToVisit::none;
} else if (lhsvar->isArgument() && (!lhstype || (lhstype->type <= ValueType::Type::VOID && !lhstype->container))) {
globalData = true;
return ChildrenToVisit::none;
}
}
if (tok->varId() == 0 && tok->isName() && tok->previous()->str() != ".") {
globalData = true;
return ChildrenToVisit::none;
}
if (tok->variable()) {
// TODO : Check references
if (tok->variable()->isReference() && tok != tok->variable()->nameToken()) {
globalData = true;
return ChildrenToVisit::none;
}
if ((tok->previous()->str() != "." && (!tok->variable()->isLocal() && !tok->variable()->isArgument())) || tok->variable()->isExtern()) {
globalData = true;
return ChildrenToVisit::none;
}
if (tok->variable()->isArgument() && tok->variable()->isPointer() && tok != expr) {
globalData = true;
return ChildrenToVisit::none;
}
}
if (Token::Match(tok, ".|["))
return ChildrenToVisit::op1;
return ChildrenToVisit::op1_and_op2;
});
return globalData;
}
FwdAnalysis::Result FwdAnalysis::check(const Token *expr, const Token *startToken, const Token *endToken)
{
// all variable ids in expr.
@ -1140,14 +1226,26 @@ FwdAnalysis::Result FwdAnalysis::check(const Token *expr, const Token *startToke
bool local = true;
visitAstNodes(expr,
[&](const Token *tok) {
if (tok->varId() == 0 && tok->isName() && tok->previous()->str() != ".")
// unknown variables are not local
local = false;
if (tok->varId() > 0) {
exprVarIds.insert(tok->varId());
if (!Token::simpleMatch(tok->previous(), "."))
if (!Token::simpleMatch(tok->previous(), ".")) {
const Variable *var = tok->variable();
if (var && var->isReference() && var->isLocal() && Token::Match(var->nameToken(), "%var% [=(]") && !isGlobalData(var->nameToken()->next()->astOperand2()))
return ChildrenToVisit::none;
local &= !nonLocal(tok->variable());
}
}
return ChildrenToVisit::op1_and_op2;
});
// In unused values checking we do not want to check assignments to
// global data.
if (mWhat == What::UnusedValue && isGlobalData(expr))
return Result(FwdAnalysis::Result::Type::BAILOUT);
Result result = checkRecursive(expr, startToken, endToken, exprVarIds, local);
// Break => continue checking in outer scope
@ -1174,7 +1272,38 @@ bool FwdAnalysis::hasOperand(const Token *tok, const Token *lhs) const
const Token *FwdAnalysis::reassign(const Token *expr, const Token *startToken, const Token *endToken)
{
mReassign = true;
mWhat = What::Reassign;
Result result = check(expr, startToken, endToken);
return result.type == FwdAnalysis::Result::Type::WRITE ? result.token : nullptr;
}
bool FwdAnalysis::unusedValue(const Token *expr, const Token *startToken, const Token *endToken)
{
mWhat = What::UnusedValue;
Result result = check(expr, startToken, endToken);
return (result.type == FwdAnalysis::Result::Type::NONE || result.type == FwdAnalysis::Result::Type::RETURN) && !possiblyAliased(expr, startToken);
}
bool FwdAnalysis::possiblyAliased(const Token *expr, const Token *startToken) const
{
if (expr->isUnaryOp("*"))
return true;
const bool macro = false;
const bool pure = false;
const bool followVar = false;
for (const Token *tok = startToken; tok; tok = tok->previous()) {
if (tok->str() == "{" && tok->scope()->type == Scope::eFunction)
continue;
if (isSameExpression(mCpp, macro, expr, tok, mLibrary, pure, followVar)) {
const Token *parent = tok->astParent();
if (parent && parent->isUnaryOp("&"))
return true;
if (parent && Token::Match(parent->tokAt(-2), "& %name% ="))
return true;
if (parent && Token::simpleMatch(parent->tokAt(-3), "std :: ref ("))
return true;
}
}
return false;
}

View File

@ -162,7 +162,7 @@ bool isLikelyStreamRead(bool cpp, const Token *op);
class FwdAnalysis {
public:
FwdAnalysis(bool cpp, const Library &library) : mCpp(cpp), mLibrary(library), mReassign(false) {}
FwdAnalysis(bool cpp, const Library &library) : mCpp(cpp), mLibrary(library), mWhat(What::Reassign) {}
bool hasOperand(const Token *tok, const Token *lhs) const;
@ -175,6 +175,18 @@ public:
*/
const Token *reassign(const Token *expr, const Token *startToken, const Token *endToken);
/**
* Check if "expr" is used. The "expr" can be a tree (x.y[12]).
* @param expr Symbolic expression to perform forward analysis for
* @param startToken First token in forward analysis
* @param endToken Last token in forward analysis
* @return true if expr is used.
*/
bool unusedValue(const Token *expr, const Token *startToken, const Token *endToken);
/** Is there some possible alias for given expression */
bool possiblyAliased(const Token *expr, const Token *startToken) const;
private:
/** Result of forward analysis */
struct Result {
@ -187,10 +199,12 @@ private:
struct Result check(const Token *expr, const Token *startToken, const Token *endToken);
struct Result checkRecursive(const Token *expr, const Token *startToken, const Token *endToken, const std::set<unsigned int> &exprVarIds, bool local);
// Is expression a l-value global data?
bool isGlobalData(const Token *expr) const;
const bool mCpp;
const Library &mLibrary;
bool mReassign;
std::vector<const Token *> mReads;
enum class What { Reassign, UnusedValue } mWhat;
};
#endif // astutilsH

View File

@ -1229,6 +1229,60 @@ void CheckUnusedVar::checkFunctionVariableUsage()
if (scope->hasInlineOrLambdaFunction())
continue;
for (const Token *tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) {
if (Token::simpleMatch(tok, "] ("))
// todo: handle lambdas
break;
if (Token::simpleMatch(tok, "try {"))
// todo: check try blocks
tok = tok->linkAt(1);
// not assignment/initialization => continue
if ((!tok->isAssignmentOp() || !tok->astOperand1()) && !(Token::Match(tok, "%var% (") && tok->variable() && tok->variable()->nameToken() == tok))
continue;
if (tok->isName()) {
if (!tok->valueType() || !tok->valueType()->isIntegral())
continue;
tok = tok->next();
}
if (tok->astParent() && tok->str() != "(") {
const Token *parent = tok->astParent();
while (Token::Match(parent, "%oror%|%comp%|!|&&"))
parent = parent->astParent();
if (!parent)
continue;
if (!Token::simpleMatch(parent->previous(), "if ("))
continue;
}
// Do not warn about assignment with NULL
if (tok->astOperand1() && tok->astOperand1()->valueType() && tok->astOperand1()->valueType()->pointer && Token::Match(tok->astOperand2(), "0|NULL|nullptr"))
continue;
if (tok->astOperand1()->variable() && tok->astOperand1()->variable()->isReference() && tok->astOperand1()->variable()->nameToken() != tok->astOperand1())
// todo: check references
continue;
if (tok->astOperand1()->variable() && tok->astOperand1()->variable()->isStatic())
// todo: check static variables
continue;
if (tok->astOperand1()->variable() && tok->astOperand1()->variable()->nameToken()->isAttributeUnused())
continue;
// Is there a redundant assignment?
const Token *start = tok->findExpressionStartEndTokens().second->next();
const Token *expr = tok->astOperand1();
if (Token::Match(expr->previous(), "%var% [") && expr->previous()->variable() && expr->previous()->variable()->nameToken() == expr->previous())
expr = expr->previous();
else if (Token::Match(expr, "& %var% ="))
expr = expr->next();
FwdAnalysis fwdAnalysis(mTokenizer->isCPP(), mSettings->library);
if (fwdAnalysis.unusedValue(expr, start, scope->bodyEnd))
// warn
unreadVariableError(tok, expr->expressionString(), false);
}
// varId, usage {read, write, modified}
Variables variables;
@ -1267,10 +1321,6 @@ void CheckUnusedVar::checkFunctionVariableUsage()
else if (usage._modified && !usage._write && !usage._allocateMemory && var && !var->isStlType())
unassignedVariableError(usage._var->nameToken(), varname);
// variable has been written but not read
else if (!usage._read)
unreadVariableError(usage._lastAccess, varname, usage._modified);
// variable has been read but not written
else if (!usage._write && !usage._allocateMemory && var && !var->isStlType() && !isEmptyType(var->type()))
unassignedVariableError(usage._var->nameToken(), varname);

View File

@ -1,6 +1,7 @@
int a[2];
int main()
{
int a[2];
a[0] = 0;
a[1] = 0;
a[2] = 0;

View File

@ -1,8 +1,9 @@
int a[3];
int main()
{
int a[3];
a[0] = 0;
a[1] = 0;
a[2] = 0;
return a[0];
return 0;
}

View File

@ -1 +1 @@
[samples\arrayIndexOutOfBounds\bad.c:6]: (error) Array 'a[2]' accessed at index 2, which is out of bounds.
[samples\arrayIndexOutOfBounds\bad.c:7]: (error) Array 'a[2]' accessed at index 2, which is out of bounds.

View File

@ -251,12 +251,14 @@ void nullpointerMemchr1(char *p, char *s)
{
// cppcheck-suppress uselessAssignmentPtrArg
p = memchr(s, 'p', strlen(s));
(void)p;
}
void nullpointerMemchr2(char *p, char *s)
{
// cppcheck-suppress uselessAssignmentPtrArg
p = memchr(s, 0, strlen(s));
(void)p;
}
void nullPointer_memchr(char *p)
@ -265,6 +267,7 @@ void nullPointer_memchr(char *p)
// cppcheck-suppress nullPointer
// cppcheck-suppress uselessAssignmentPtrArg
p = memchr(s, 0, strlen(s));
(void)p;
}
void nullPointer_memcmp(char *p)

View File

@ -257,6 +257,7 @@ void nullPointer()
//Incorrect: 1. parameter, must not be null
// cppcheck-suppress nullPointer
FARPROC pAddr = GetProcAddress(NULL, "name");
(void)pAddr;
HMODULE * phModule = NULL;
// cppcheck-suppress nullPointer
GetModuleHandleEx(0, NULL, phModule);

View File

@ -26,6 +26,7 @@
void validCode()
{
wxString str = wxGetCwd();
(void)str;
wxLogGeneric(wxLOG_Message, "test %d", 0);
wxLogMessage("test %s", "str");
@ -33,6 +34,9 @@ void validCode()
wxString translation1 = _("text");
wxString translation2 = wxGetTranslation("text");
wxString translation3 = wxGetTranslation("string", "domain");
(void)translation1;
(void)translation2;
(void)translation3;
}
#if wxUSE_GUI==1

View File

@ -105,6 +105,8 @@ private:
TEST_CASE(localvar49); // ticket #7594
TEST_CASE(localvar50); // ticket #6261 : dostuff(cond ? buf1 : buf2)
TEST_CASE(localvar51); // ticket #8128 - FN : tok = tok->next();
TEST_CASE(localvar52);
TEST_CASE(localvar53); // continue
TEST_CASE(localvaralias1);
TEST_CASE(localvaralias2); // ticket #1637
TEST_CASE(localvaralias3); // ticket #1639
@ -120,6 +122,7 @@ private:
TEST_CASE(localvaralias13); // ticket #4487
TEST_CASE(localvaralias14); // ticket #5619
TEST_CASE(localvaralias15); // ticket #6315
TEST_CASE(localvaralias16);
TEST_CASE(localvarasm);
TEST_CASE(localvarstatic);
TEST_CASE(localvarextern);
@ -185,6 +188,8 @@ private:
TEST_CASE(lambdaFunction); // #5078
TEST_CASE(namespaces); // #7557
TEST_CASE(bracesInitCpp11);// #7895 - "int var{123}" initialization
TEST_CASE(argument);
}
void checkStructMemberUsage(const char code[]) {
@ -556,7 +561,7 @@ private:
" int & i = j;\n"
" x(j);\n"
"}");
ASSERT_EQUALS("", errout.str());
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -564,7 +569,7 @@ private:
" const int & i = j;\n"
" x(j);\n"
"}");
ASSERT_EQUALS("", errout.str());
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -584,14 +589,14 @@ private:
functionVariableUsage("void foo()\n"
"{\n"
" int * j = 0;\n"
" int * j = Data;\n"
" int * i(j);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int * j = 0;\n"
" int * j = Data;\n"
" const int * i(j);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
@ -620,7 +625,7 @@ private:
"{\n"
" undefined i = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
// ? ASSERT_EQUALS("", errout.str());
functionVariableUsage("undefined foo()\n"
"{\n"
@ -637,31 +642,31 @@ private:
functionVariableUsage("void foo()\n"
"{\n"
" int * i = 0;\n"
" int * i = Data;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" void * i = 0;\n"
" void * i = Data;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" const void * i = 0;\n"
" const void * i = Data;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" struct S * i = 0;\n"
" struct S * i = DATA;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" const struct S * i = 0;\n"
" const struct S * i = DATA;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
@ -679,7 +684,7 @@ private:
functionVariableUsage("void foo()\n"
"{\n"
" undefined * i = 0;\n"
" undefined * i = X;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
@ -739,7 +744,7 @@ private:
" d = code;\n"
" }\n"
"}");
ASSERT_EQUALS("[test.cpp:7]: (style) Variable 'd' is assigned a value that is never used.\n", errout.str());
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'd' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -1130,7 +1135,7 @@ private:
" for (int i=0;i<10;++i)\n"
" b[i] = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -1139,7 +1144,7 @@ private:
" for (int i=0;i<10;++i)\n"
" b[i] = ++a;\n"
"}");
ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
}
void localvar7() { // ticket 1253
@ -1156,8 +1161,8 @@ private:
" int &ii(i);\n"
" ii--;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is not assigned a value.\n"
"[test.cpp:5]: (style) Variable 'ii' is modified but its new value is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is not assigned a value.\n"
// TODO "[test.cpp:5]: (style) Variable 'ii' is modified but its new value is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -1165,8 +1170,8 @@ private:
" int &ii=i;\n"
" ii--;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is not assigned a value.\n"
"[test.cpp:5]: (style) Variable 'ii' is modified but its new value is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is not assigned a value.\n"
// TODO "[test.cpp:5]: (style) Variable 'ii' is modified but its new value is never used.\n", errout.str());
}
void localvar8() {
@ -1259,16 +1264,15 @@ private:
" int i = 0;\n"
" int &j = i;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n"
"[test.cpp:4]: (style) Variable 'j' is assigned a value that is never used.\n", errout.str());
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'j' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int i;\n"
" int &j = i;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n"
"[test.cpp:4]: (style) Variable 'j' is assigned a value that is never used.\n", errout.str());
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'j' is assigned a value that is never used.\n"
"[test.cpp:3]: (style) Unused variable: i\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -1276,7 +1280,7 @@ private:
" int &j = i;\n"
" j = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("double foo()\n"
"{\n"
@ -1359,9 +1363,7 @@ private:
" int a, b, c;\n"
" a = b = c = f();\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'a' is assigned a value that is never used.\n"
"[test.cpp:4]: (style) Variable 'b' is assigned a value that is never used.\n"
"[test.cpp:4]: (style) Variable 'c' is assigned a value that is never used.\n", errout.str());
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("int * foo()\n"
"{\n"
@ -1378,7 +1380,7 @@ private:
" for (int i = 0; i < 10; )\n"
" a[i++] = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
}
void localvar10() {
@ -1416,9 +1418,9 @@ private:
" int i = 0;\n"
" }\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n"
"[test.cpp:5]: (style) Unused variable: i\n"
"[test.cpp:7]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
ASSERT_EQUALS("[test.cpp:7]: (style) Variable 'i' is assigned a value that is never used.\n"
"[test.cpp:3]: (style) Unused variable: i\n"
"[test.cpp:5]: (style) Unused variable: i\n", errout.str());
functionVariableUsage("void foo(int x)\n"
"{\n"
@ -1428,7 +1430,7 @@ private:
" } else {\n"
" int i;\n"
" }\n"
" i = 0;\n"
" i = 1;\n"
"}");
ASSERT_EQUALS("[test.cpp:9]: (style) Variable 'i' is assigned a value that is never used.\n"
"[test.cpp:5]: (style) Unused variable: i\n"
@ -1444,9 +1446,10 @@ private:
" a = 123;\n" // redundant assignment
" return;\n"
" }\n"
" x = a;\n"
" x = a;\n" // redundant assignment
"}");
ASSERT_EQUALS("", errout.str());
ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'a' is assigned a value that is never used.\n"
"[test.cpp:9]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
// The variable 'a' is initialized. But the initialized value is
// never used. It is only initialized for security reasons.
@ -1461,7 +1464,7 @@ private:
" return;\n"
" x = a;\n"
"}");
ASSERT_EQUALS("", errout.str());
ASSERT_EQUALS("[test.cpp:10]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
}
void localvar12() {
@ -1469,8 +1472,7 @@ private:
functionVariableUsage("void foo()\n"
"{\n"
" int a, b, c, d, e, f;\n"
" a = b = c = d = e = f = 0;\n"
"\n"
" a = b = c = d = e = f = 15;\n"
"}");
ASSERT_EQUALS(
"[test.cpp:4]: (style) Variable 'a' is assigned a value that is never used.\n"
@ -1570,7 +1572,7 @@ private:
" char *ptr = buf;\n"
" *(ptr++) = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'buf' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'buf' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("int foo()\n"
"{\n"
@ -1604,7 +1606,7 @@ private:
// Don't crash when checking the code below!
functionVariableUsage("void foo()\n"
"{\n"
" struct DATA *data;\n"
" struct DATA *data = DATA;\n"
" char *k = data->req;\n"
" char *ptr;\n"
" char *line_start;\n"
@ -1630,8 +1632,8 @@ private:
" int c;\n"
" c = *(a);\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'a' is not assigned a value.\n"
"[test.cpp:4]: (style) Variable 'c' is assigned a value that is never used.\n", errout.str());
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'c' is assigned a value that is never used.\n"
"[test.cpp:2]: (style) Variable 'a' is not assigned a value.\n", errout.str());
}
void localvar20() { // ticket #1799
@ -1672,7 +1674,7 @@ private:
" a = b[c] = 0;\n"
" return a;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
}
void localvar24() { // ticket #1803
@ -1758,19 +1760,17 @@ private:
ASSERT_EQUALS("", errout.str());
// ticket #4596 - if (c >>= x) {}
functionVariableUsage("void f() {\n"
" int x;\n"
functionVariableUsage("void f(int x) {\n"
" C c;\n" // possibly some stream class
" if (c >>= x) {}\n"
"}");
ASSERT_EQUALS("", errout.str());
// TODO ASSERT_EQUALS("", errout.str());
functionVariableUsage("void f() {\n"
" int x;\n"
functionVariableUsage("void f(int x) {\n"
" C c;\n"
" if (c >>= x) {}\n"
"}", "test.c");
ASSERT_EQUALS("[test.c:4]: (style) Variable 'c' is assigned a value that is never used.\n", errout.str());
ASSERT_EQUALS("[test.c:3]: (style) Variable 'c' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void f(int c) {\n"
" int x;\n"
@ -2033,9 +2033,9 @@ private:
" return \"x\";\n"
"}\n"
"void A::DoSomething(void) {\n"
" const std::string x = Bar();\n"
" const std::string x = Bar();\n" // <- warning
"}");
ASSERT_EQUALS("[test.cpp:16]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:16]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
}
void localvar50() { // #6261, #6542
@ -2068,12 +2068,45 @@ private:
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'tok' is assigned a value that is never used.\n", errout.str());
// TODO: False negative
functionVariableUsage("void foo() {\n"
" int x = 4;\n"
" x = 15 + x;\n" // read+write
"}");
TODO_ASSERT_EQUALS("error", "", errout.str());
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
}
void localvar52() {
functionVariableUsage("void foo() {\n"
" std::vector<int> data;\n"
" data[2] = 32;\n"
" return data;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar53() {
functionVariableUsage("void foo() {\n"
" bool x = false;\n"
" while (loop) {\n"
" if (a) {\n"
" x = true;\n" // unused value
" continue;\n"
" }\n"
" }\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo() {\n"
" bool x = false;\n"
" while (loop) {\n"
" if (a) {\n"
" x = true;\n"
" continue;\n"
" }\n"
" }\n"
" return x;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
}
void localvaralias1() {
@ -2082,16 +2115,16 @@ private:
" int a;\n"
" int *b = &a;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: a\n"
"[test.cpp:4]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'b' is assigned a value that is never used.\n"
"[test.cpp:3]: (style) Unused variable: a\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a[10];\n"
" int *b = a;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: a\n"
"[test.cpp:4]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'b' is assigned a value that is never used.\n"
"[test.cpp:3]: (style) Unused variable: a\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -2099,7 +2132,7 @@ private:
" int *b = &a;\n"
" *b = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -2107,7 +2140,7 @@ private:
" char *b = (char *)&a;\n"
" *b = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -2115,7 +2148,7 @@ private:
" char *b = (char *)(&a);\n"
" *b = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -2123,7 +2156,7 @@ private:
" const char *b = (const char *)&a;\n"
" *b = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -2131,7 +2164,7 @@ private:
" const char *b = (const char *)(&a);\n"
" *b = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -2139,7 +2172,7 @@ private:
" char *b = static_cast<char *>(&a);\n"
" *b = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -2147,7 +2180,7 @@ private:
" const char *b = static_cast<const char *>(&a);\n"
" *b = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
// a is not a local variable and b is aliased to it
functionVariableUsage("int a;\n"
@ -2207,7 +2240,7 @@ private:
" int *b = a;\n"
" *b = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -2215,7 +2248,7 @@ private:
" char *b = (char *)a;\n"
" *b = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -2223,7 +2256,7 @@ private:
" char *b = (char *)(a);\n"
" *b = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -2231,7 +2264,7 @@ private:
" const char *b = (const char *)a;\n"
" *b = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -2239,7 +2272,7 @@ private:
" const char *b = (const char *)(a);\n"
" *b = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -2247,7 +2280,7 @@ private:
" char *b = static_cast<char *>(a);\n"
" *b = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -2255,7 +2288,7 @@ private:
" const char *b = static_cast<const char *>(a);\n"
" *b = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("int a[10];\n"
"void foo()\n"
@ -2362,7 +2395,7 @@ private:
" int *c = b;\n"
" *c = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -2372,9 +2405,9 @@ private:
" int *d = b;\n"
" *d = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: a\n"
"[test.cpp:7]: (style) Variable 'b' is assigned a value that is never used.\n"
"[test.cpp:5]: (style) Variable 'c' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: a\n"
// TODO "[test.cpp:7]: (style) Variable 'b' is assigned a value that is never used.\n"
// TODO "[test.cpp:5]: (style) Variable 'c' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -2384,8 +2417,8 @@ private:
" c = b;\n"
" *c = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: a\n"
"[test.cpp:7]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: a\n"
// TODO "[test.cpp:7]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -2397,15 +2430,15 @@ private:
" c = a;\n"
" *c = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:9]: (style) Variable 'a' is assigned a value that is never used.\n"
"[test.cpp:7]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:9]: (style) Variable 'a' is assigned a value that is never used.\n"
// TODO "[test.cpp:7]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a[10], * b = a + 10;\n"
" b[-10] = 0;\n"
" b[-10] = 1;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'b[-10]' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -2413,8 +2446,8 @@ private:
" b[-10] = 0;\n"
" int * c = b - 10;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'a' is assigned a value that is never used.\n"
"[test.cpp:5]: (style) Variable 'c' is assigned a value that is never used.\n", errout.str());
ASSERT_EQUALS(// TODO "[test.cpp:4]: (style) Variable 'a' is assigned a value that is never used.\n"
"[test.cpp:5]: (style) Variable 'c' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -2428,9 +2461,9 @@ private:
"{\n"
" int a[10], * b = a + 10;\n"
" int * c = b - 10;\n"
" c[1] = 0;\n"
" c[1] = 3;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'c[1]' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -2438,7 +2471,7 @@ private:
" int * c = b - 10;\n"
" c[1] = c[0];\n"
"}");
ASSERT_EQUALS("", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'c[1]' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -2482,8 +2515,8 @@ private:
" char a[100];\n"
" struct S * s = (struct S *)a;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Unused variable: a\n"
"[test.cpp:5]: (style) Variable 's' is assigned a value that is never used.\n", errout.str());
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 's' is assigned a value that is never used.\n"
"[test.cpp:4]: (style) Unused variable: a\n", errout.str());
functionVariableUsage("struct S { char c[100]; };\n"
"void foo()\n"
@ -2491,8 +2524,8 @@ private:
" char a[100];\n"
" const struct S * s = (const struct S *)a;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Unused variable: a\n"
"[test.cpp:5]: (style) Variable 's' is assigned a value that is never used.\n", errout.str());
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 's' is assigned a value that is never used.\n"
"[test.cpp:4]: (style) Unused variable: a\n", errout.str());
functionVariableUsage("struct S { char c[100]; };\n"
"void foo()\n"
@ -2500,8 +2533,8 @@ private:
" char a[100];\n"
" struct S * s = static_cast<struct S *>(a);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Unused variable: a\n"
"[test.cpp:5]: (style) Variable 's' is assigned a value that is never used.\n", errout.str());
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 's' is assigned a value that is never used.\n"
"[test.cpp:4]: (style) Unused variable: a\n", errout.str());
functionVariableUsage("struct S { char c[100]; };\n"
"void foo()\n"
@ -2509,8 +2542,8 @@ private:
" char a[100];\n"
" const struct S * s = static_cast<const struct S *>(a);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Unused variable: a\n"
"[test.cpp:5]: (style) Variable 's' is assigned a value that is never used.\n", errout.str());
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 's' is assigned a value that is never used.\n"
"[test.cpp:4]: (style) Unused variable: a\n", errout.str());
functionVariableUsage("int a[10];\n"
"void foo()\n"
@ -2523,8 +2556,8 @@ private:
" d = c;\n"
" *d = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Unused variable: b\n"
"[test.cpp:10]: (style) Variable 'c' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:4]: (style) Unused variable: b\n"
// TODO "[test.cpp:10]: (style) Variable 'c' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("int a[10];\n"
"void foo()\n"
@ -2536,8 +2569,8 @@ private:
" d = a; *d = 0;\n"
" d = c; *d = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:7]: (style) Variable 'b' is assigned a value that is never used.\n"
"[test.cpp:9]: (style) Variable 'c' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:7]: (style) Variable 'b' is assigned a value that is never used.\n"
// TODO "[test.cpp:9]: (style) Variable 'c' is assigned a value that is never used.\n", errout.str());
}
void localvaralias2() { // ticket 1637
@ -2582,8 +2615,8 @@ private:
" struct AB ab;\n"
" int * a = &ab.a;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ab' is not assigned a value.\n"
"[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n"
"[test.cpp:4]: (style) Variable 'ab' is not assigned a value.\n", errout.str());
functionVariableUsage("struct AB { int a; int b; };\n"
"void foo()\n"
@ -2659,7 +2692,7 @@ private:
" }\n"
" b(srcdata);\n"
"}");
ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'buf' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'buf' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -2672,7 +2705,7 @@ private:
" srcdata = vdata;\n"
" b(srcdata);\n"
"}");
ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'buf' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'buf' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -2725,7 +2758,7 @@ private:
" }\n"
" b(srcdata);\n"
"}");
ASSERT_EQUALS("[test.cpp:7]: (style) Variable 'buf' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:7]: (style) Variable 'buf' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -2739,7 +2772,7 @@ private:
" srcdata = vdata;\n"
" b(srcdata);\n"
"}");
ASSERT_EQUALS("[test.cpp:7]: (style) Variable 'buf' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:7]: (style) Variable 'buf' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -2980,7 +3013,7 @@ private:
" ref[0] = 123;\n"
"}",
"test.c");
ASSERT_EQUALS("[test.c:5]: (style) Variable 'foo' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.c:5]: (style) Variable 'foo' is assigned a value that is never used.\n", errout.str());
}
void localvaralias10() { // ticket 2004
@ -3047,7 +3080,7 @@ private:
" char a[4], *p=a;\n"
" p = dostuff(p);\n"
"}");
TODO_ASSERT_EQUALS("p is assigned a value that is never used", "", errout.str());
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'p' is assigned a value that is never used.\n", errout.str());
}
void localvaralias15() { // #6315
@ -3060,7 +3093,17 @@ private:
ASSERT_EQUALS("", errout.str());
}
void localvaralias16() {
functionVariableUsage("void f() {\n"
" auto x = dostuff();\n"
" p = x;\n"
" x->data[0] = 9;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarasm() {
functionVariableUsage("void foo(int &b)\n"
"{\n"
" int a;\n"
@ -3141,7 +3184,7 @@ private:
" a.i = 0;\n"
" return 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'a.i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("class A { int i; };\n"
"int foo() {\n"
@ -3149,7 +3192,7 @@ private:
" a.i = 0;\n"
" return 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'a.i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("struct A { int i; };\n"
"int foo() {\n"
@ -3231,9 +3274,9 @@ private:
// #3633 - detect that struct array is assigned a value
functionVariableUsage("void f() {\n"
" struct X x[10];\n"
" x[0].a = 0;\n"
" x[0].a = 5;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'x[0].a' is assigned a value that is never used.\n", errout.str());
}
void localvarOp() {
@ -3318,12 +3361,13 @@ private:
"}");
ASSERT_EQUALS("", errout.str());
// FIXME : this is probably inconclusive
functionVariableUsage("void f() {\n"
" Fred fred;\n"
" int *a; a = b;\n"
" fred += a;\n"
"}");
ASSERT_EQUALS("", errout.str());
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'fred' is assigned a value that is never used.\n", errout.str());
}
void localvarFor() {
@ -3461,26 +3505,26 @@ private:
"{\n"
" static int i;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" static int i = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" static int i(0);\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" static int j = 0;\n"
" static int i(j);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("int * foo(int x)\n"
"{\n"
@ -3490,7 +3534,7 @@ private:
" b[1] = 1;\n"
" return x ? a : c;\n"
"}");
ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -3764,7 +3808,7 @@ private:
" for ( int i = 0; i < 10; ++i )\n"
" p++;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'p' is modified but its new value is never used.\n", errout.str());
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'p' is modified but its new value is never used.\n", errout.str());
}
void localvararray1() {
@ -3992,7 +4036,7 @@ private:
" }\n"
" return false;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'X' is assigned a value that is never used.\n", errout.str());
// #4558
functionVariableUsage("int f() {\n"
@ -4222,6 +4266,22 @@ private:
);
ASSERT_EQUALS("", errout.str());
}
void argument() {
functionVariableUsage(
"void fun(Value value) {\n"
" value[10] = 123;\n"
"}\n"
);
ASSERT_EQUALS("", errout.str());
functionVariableUsage(
"void fun(std::string s) {\n"
" s[10] = 123;\n"
"}\n"
);
// TODO This works on command line.. load std.cfg? ASSERT_EQUALS("error", errout.str());
}
};
REGISTER_TEST(TestUnusedVar)