Check if member function modifies the variable (#1350)
* Check if member function modifies the variable * Check for const pointer * Add test for const condition * Add more null checking * Add todo assert for FN
This commit is contained in:
parent
acb0b9f07e
commit
fc135e1087
|
@ -779,6 +779,21 @@ bool isVariableChanged(const Token *start, const Token *end, const unsigned int
|
||||||
if (isLikelyStreamRead(cpp, tok->previous()))
|
if (isLikelyStreamRead(cpp, tok->previous()))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// Member function call
|
||||||
|
if(Token::Match(tok, "%name% . %name% (")) {
|
||||||
|
const Variable * var = tok->variable();
|
||||||
|
bool isConst = var && var->isConst();
|
||||||
|
if(!isConst && var) {
|
||||||
|
const ValueType * valueType = var->valueType();
|
||||||
|
isConst = (valueType && valueType->pointer == 1 && valueType->constness == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Token *ftok = tok->tokAt(2);
|
||||||
|
const Function * fun = ftok->function();
|
||||||
|
if(!isConst && (!fun || !fun->isConst()))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const Token *ftok = tok;
|
const Token *ftok = tok;
|
||||||
while (ftok && !Token::Match(ftok, "[({[]"))
|
while (ftok && !Token::Match(ftok, "[({[]"))
|
||||||
ftok = ftok->astParent();
|
ftok = ftok->astParent();
|
||||||
|
|
|
@ -71,6 +71,7 @@ private:
|
||||||
TEST_CASE(incorrectLogicOperator9);
|
TEST_CASE(incorrectLogicOperator9);
|
||||||
TEST_CASE(incorrectLogicOperator10); // enum
|
TEST_CASE(incorrectLogicOperator10); // enum
|
||||||
TEST_CASE(incorrectLogicOperator11);
|
TEST_CASE(incorrectLogicOperator11);
|
||||||
|
TEST_CASE(incorrectLogicOperator12);
|
||||||
TEST_CASE(secondAlwaysTrueFalseWhenFirstTrueError);
|
TEST_CASE(secondAlwaysTrueFalseWhenFirstTrueError);
|
||||||
TEST_CASE(incorrectLogicOp_condSwapping);
|
TEST_CASE(incorrectLogicOp_condSwapping);
|
||||||
TEST_CASE(testBug5895);
|
TEST_CASE(testBug5895);
|
||||||
|
@ -1233,6 +1234,50 @@ private:
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (warning) Logical conjunction always evaluates to false: i == n && i < n.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1]: (warning) Logical conjunction always evaluates to false: i == n && i < n.\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void incorrectLogicOperator12() { // #8696
|
||||||
|
check("struct A {\n"
|
||||||
|
" void f() const;\n"
|
||||||
|
"};\n"
|
||||||
|
"void foo(A a) {\n"
|
||||||
|
" A x = a;\n"
|
||||||
|
" A y = a;\n"
|
||||||
|
" y.f();\n"
|
||||||
|
" if (a > x && a < y)\n"
|
||||||
|
" return;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:8]: (warning) Logical conjunction always evaluates to false: a > x && a < y.\n", errout.str());
|
||||||
|
|
||||||
|
check("struct A {\n"
|
||||||
|
" void f();\n"
|
||||||
|
"};\n"
|
||||||
|
"void foo(A a) {\n"
|
||||||
|
" A x = a;\n"
|
||||||
|
" A y = a;\n"
|
||||||
|
" y.f();\n"
|
||||||
|
" if (a > x && a < y)\n"
|
||||||
|
" return;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("void foo(A a) {\n"
|
||||||
|
" A x = a;\n"
|
||||||
|
" A y = a;\n"
|
||||||
|
" y.f();\n"
|
||||||
|
" if (a > x && a < y)\n"
|
||||||
|
" return;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("void foo(A a) {\n"
|
||||||
|
" const A x = a;\n"
|
||||||
|
" const A y = a;\n"
|
||||||
|
" y.f();\n"
|
||||||
|
" if (a > x && a < y)\n"
|
||||||
|
" return;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:5]: (warning) Logical conjunction always evaluates to false: a > x && a < y.\n", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void secondAlwaysTrueFalseWhenFirstTrueError() {
|
void secondAlwaysTrueFalseWhenFirstTrueError() {
|
||||||
check("void f(int x) {\n"
|
check("void f(int x) {\n"
|
||||||
" if (x > 5 && x != 1)\n"
|
" if (x > 5 && x != 1)\n"
|
||||||
|
|
|
@ -3126,12 +3126,19 @@ private:
|
||||||
ASSERT_EQUALS(true, values.size()==1U && values.front().isUninitValue());
|
ASSERT_EQUALS(true, values.size()==1U && values.front().isUninitValue());
|
||||||
|
|
||||||
code = "void f() {\n"
|
code = "void f() {\n"
|
||||||
" C *c;\n"
|
" const C *c;\n"
|
||||||
" if (c->x() == 4) {}\n"
|
" if (c->x() == 4) {}\n"
|
||||||
"}";
|
"}";
|
||||||
values = tokenValues(code, "c .");
|
values = tokenValues(code, "c .");
|
||||||
ASSERT_EQUALS(true, values.size()==1U && values.front().isUninitValue());
|
ASSERT_EQUALS(true, values.size()==1U && values.front().isUninitValue());
|
||||||
|
|
||||||
|
code = "void f() {\n"
|
||||||
|
" C *c;\n"
|
||||||
|
" if (c->x() == 4) {}\n"
|
||||||
|
"}";
|
||||||
|
values = tokenValues(code, "c .");
|
||||||
|
TODO_ASSERT_EQUALS(true, false, values.size()==1U && values.front().isUninitValue());
|
||||||
|
|
||||||
code = "void f() {\n"
|
code = "void f() {\n"
|
||||||
" int **x;\n"
|
" int **x;\n"
|
||||||
" y += 10;\n"
|
" y += 10;\n"
|
||||||
|
|
Loading…
Reference in New Issue