diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 5f22ce05b..46c6de519 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -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; +} diff --git a/lib/astutils.h b/lib/astutils.h index 6abc6623a..17d276b71 100644 --- a/lib/astutils.h +++ b/lib/astutils.h @@ -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 &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 mReads; + enum class What { Reassign, UnusedValue } mWhat; }; #endif // astutilsH diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index 07552bd15..020f588f1 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -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); diff --git a/samples/arrayIndexOutOfBounds/bad.c b/samples/arrayIndexOutOfBounds/bad.c index e738cbcd0..ac99ea215 100644 --- a/samples/arrayIndexOutOfBounds/bad.c +++ b/samples/arrayIndexOutOfBounds/bad.c @@ -1,6 +1,7 @@ +int a[2]; + int main() { - int a[2]; a[0] = 0; a[1] = 0; a[2] = 0; diff --git a/samples/arrayIndexOutOfBounds/good.c b/samples/arrayIndexOutOfBounds/good.c index 7b42abfec..cbce96de6 100644 --- a/samples/arrayIndexOutOfBounds/good.c +++ b/samples/arrayIndexOutOfBounds/good.c @@ -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; } diff --git a/samples/arrayIndexOutOfBounds/out.txt b/samples/arrayIndexOutOfBounds/out.txt index f05a3337a..63ea20f96 100644 --- a/samples/arrayIndexOutOfBounds/out.txt +++ b/samples/arrayIndexOutOfBounds/out.txt @@ -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. diff --git a/test/cfg/std.c b/test/cfg/std.c index 07137e44c..bd9184e82 100644 --- a/test/cfg/std.c +++ b/test/cfg/std.c @@ -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) diff --git a/test/cfg/windows.cpp b/test/cfg/windows.cpp index 9bec2086a..b9134f63e 100644 --- a/test/cfg/windows.cpp +++ b/test/cfg/windows.cpp @@ -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); diff --git a/test/cfg/wxwidgets.cpp b/test/cfg/wxwidgets.cpp index eab49c826..5fa9b0de8 100644 --- a/test/cfg/wxwidgets.cpp +++ b/test/cfg/wxwidgets.cpp @@ -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 diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 9f145ca50..7cc846a34 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -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 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(&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(&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(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(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(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(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)