checkunusedvar: handle array element change using pointer arithmetic (#3000)
This commit is contained in:
parent
8dc8aa0459
commit
ee8d5b972a
|
@ -1681,6 +1681,23 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings,
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (indirect > 0)
|
||||||
|
{
|
||||||
|
// check for `*(ptr + 1) = new_value` case
|
||||||
|
parent = tok2->astParent();
|
||||||
|
while (parent && parent->isArithmeticalOp() && parent->isBinaryOp()) {
|
||||||
|
parent = parent->astParent();
|
||||||
|
}
|
||||||
|
if (Token::simpleMatch(parent, "*"))
|
||||||
|
{
|
||||||
|
if (parent->astParent() && parent->astParent()->isAssignmentOp() &&
|
||||||
|
(parent->astParent()->astOperand1() == parent)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1620,9 +1620,6 @@ bool CheckUnusedVar::isFunctionWithoutSideEffects(const Function& func, const To
|
||||||
}
|
}
|
||||||
// check if global variable is changed
|
// check if global variable is changed
|
||||||
if (bodyVariable->isGlobal() || (pointersToGlobals.find(bodyVariable) != pointersToGlobals.end())) {
|
if (bodyVariable->isGlobal() || (pointersToGlobals.find(bodyVariable) != pointersToGlobals.end())) {
|
||||||
if (bodyVariable->isPointer() || bodyVariable->isArray()) {
|
|
||||||
return false; // TODO: Update astutils.cpp:1544 isVariableChanged() and remove this. Unhandled case: `*(global_arr + 1) = new_val`
|
|
||||||
}
|
|
||||||
const int depth = 20;
|
const int depth = 20;
|
||||||
if (isVariableChanged(bodyToken, depth, mSettings, mTokenizer->isCPP())) {
|
if (isVariableChanged(bodyToken, depth, mSettings, mTokenizer->isCPP())) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -748,6 +748,23 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
functionVariableUsage(
|
||||||
|
"int x[] = {0, 1, 3};\n"
|
||||||
|
"int func() {\n"
|
||||||
|
" *(x) = 2;\n"
|
||||||
|
" return 1;\n"
|
||||||
|
"}\n"
|
||||||
|
"class C {\n"
|
||||||
|
"public:\n"
|
||||||
|
" C() : x(func()) {}\n"
|
||||||
|
" int x;\n"
|
||||||
|
"};\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" C c;\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
// pointer arithmetic on global array
|
||||||
functionVariableUsage(
|
functionVariableUsage(
|
||||||
"int x[] = {0, 1, 3};\n"
|
"int x[] = {0, 1, 3};\n"
|
||||||
"int func() {\n"
|
"int func() {\n"
|
||||||
|
@ -764,6 +781,87 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
functionVariableUsage(
|
||||||
|
"int x[][] = {{0, 1}, {2, 3}};\n"
|
||||||
|
"int func() {\n"
|
||||||
|
" *((x + 1) + 1) = 4;\n"
|
||||||
|
" return 1;\n"
|
||||||
|
"}\n"
|
||||||
|
"class C {\n"
|
||||||
|
"public:\n"
|
||||||
|
" C() : x(func()) {}\n"
|
||||||
|
" int x;\n"
|
||||||
|
"};\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" C c;\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
functionVariableUsage(
|
||||||
|
"int x[] = {0, 1, 3};\n"
|
||||||
|
"int func() {\n"
|
||||||
|
" int local = *(x + 1);\n"
|
||||||
|
" (void) local;\n"
|
||||||
|
" return 1;\n"
|
||||||
|
"}\n"
|
||||||
|
"class C {\n"
|
||||||
|
"public:\n"
|
||||||
|
" C() : x(func()) {}\n"
|
||||||
|
" int x;\n"
|
||||||
|
"};\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" C c;\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:13]: (style) Unused variable: c\n", errout.str());
|
||||||
|
|
||||||
|
functionVariableUsage(
|
||||||
|
"int x[] = {0, 1, 3};\n"
|
||||||
|
"int func() {\n"
|
||||||
|
" int* local = x + 2;\n"
|
||||||
|
" (void) local;\n"
|
||||||
|
" return 1;\n"
|
||||||
|
"}\n"
|
||||||
|
"class C {\n"
|
||||||
|
"public:\n"
|
||||||
|
" C() : x(func()) {}\n"
|
||||||
|
" int x;\n"
|
||||||
|
"};\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" C c;\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:13]: (style) Unused variable: c\n", errout.str());
|
||||||
|
|
||||||
|
functionVariableUsage(
|
||||||
|
"int x[] = {0, 1, 3};\n"
|
||||||
|
"int func() {\n"
|
||||||
|
" int* local = x + 2;\n"
|
||||||
|
" return *local;\n"
|
||||||
|
"}\n"
|
||||||
|
"class C {\n"
|
||||||
|
"public:\n"
|
||||||
|
" C() : x(func()) {}\n"
|
||||||
|
" int x;\n"
|
||||||
|
"};\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" C c;\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
functionVariableUsage(
|
||||||
|
"int x[] = {0, 1, 3};\n"
|
||||||
|
"int func() {\n"
|
||||||
|
" return *(x + 1);\n"
|
||||||
|
"}\n"
|
||||||
|
"class C {\n"
|
||||||
|
"public:\n"
|
||||||
|
" C() : x(func()) {}\n"
|
||||||
|
" int x;\n"
|
||||||
|
"};\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" C c;\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
// changing local variable
|
// changing local variable
|
||||||
functionVariableUsage(
|
functionVariableUsage(
|
||||||
"int func() {\n"
|
"int func() {\n"
|
||||||
|
@ -1064,8 +1162,7 @@ private:
|
||||||
"void f() {\n"
|
"void f() {\n"
|
||||||
" C c;\n"
|
" C c;\n"
|
||||||
"}");
|
"}");
|
||||||
// TODO: see TODO for global vars under CheckUnusedVar::isFunctionWithoutSideEffects()
|
ASSERT_EQUALS("[test.cpp:13]: (style) Unused variable: c\n", errout.str());
|
||||||
TODO_ASSERT_EQUALS("[test.cpp:13]: (style) Unused variable: c\n", "", errout.str());
|
|
||||||
|
|
||||||
// global struct variable modification
|
// global struct variable modification
|
||||||
functionVariableUsage(
|
functionVariableUsage(
|
||||||
|
@ -1135,8 +1232,7 @@ private:
|
||||||
"void f() {\n"
|
"void f() {\n"
|
||||||
" C c;\n"
|
" C c;\n"
|
||||||
"}");
|
"}");
|
||||||
// TODO: see TODO for global vars under CheckUnusedVar::isFunctionWithoutSideEffects()
|
ASSERT_EQUALS("[test.cpp:13]: (style) Unused variable: c\n", errout.str());
|
||||||
TODO_ASSERT_EQUALS("[test.cpp:13]: (style) Unused variable: c\n", "", errout.str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// #5355 - False positive: Variable is not assigned a value.
|
// #5355 - False positive: Variable is not assigned a value.
|
||||||
|
|
Loading…
Reference in New Issue