Consider pre{inc,dec}rements on assert checks (#2605)
* Consider pre{inc,dec}rements on assert checks * Simplify code by using new AST APIs * Fix assert test with invalid syntax
This commit is contained in:
parent
453a69dd8c
commit
7c93f51885
|
@ -120,13 +120,16 @@ void CheckAssert::assignmentInAssertError(const Token *tok, const std::string& v
|
||||||
// checks if side effects happen on the variable prior to tmp
|
// checks if side effects happen on the variable prior to tmp
|
||||||
void CheckAssert::checkVariableAssignment(const Token* assignTok, const Scope *assertionScope)
|
void CheckAssert::checkVariableAssignment(const Token* assignTok, const Scope *assertionScope)
|
||||||
{
|
{
|
||||||
const Variable* prevVar = assignTok->previous()->variable();
|
if (!assignTok->isAssignmentOp() && assignTok->tokType() != Token::eIncDecOp)
|
||||||
if (!prevVar)
|
return;
|
||||||
|
|
||||||
|
const Variable* var = assignTok->astOperand1()->variable();
|
||||||
|
if (!var)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Variable declared in inner scope in assert => don't warn
|
// Variable declared in inner scope in assert => don't warn
|
||||||
if (assertionScope != prevVar->scope()) {
|
if (assertionScope != var->scope()) {
|
||||||
const Scope *s = prevVar->scope();
|
const Scope *s = var->scope();
|
||||||
while (s && s != assertionScope)
|
while (s && s != assertionScope)
|
||||||
s = s->nestedIn;
|
s = s->nestedIn;
|
||||||
if (s == assertionScope)
|
if (s == assertionScope)
|
||||||
|
@ -135,12 +138,12 @@ void CheckAssert::checkVariableAssignment(const Token* assignTok, const Scope *a
|
||||||
|
|
||||||
// assignment
|
// assignment
|
||||||
if (assignTok->isAssignmentOp() || assignTok->tokType() == Token::eIncDecOp) {
|
if (assignTok->isAssignmentOp() || assignTok->tokType() == Token::eIncDecOp) {
|
||||||
if (prevVar->isConst())
|
if (var->isConst()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
assignmentInAssertError(assignTok, prevVar->name());
|
assignmentInAssertError(assignTok, var->name());
|
||||||
}
|
}
|
||||||
// TODO: function calls on prevVar
|
// TODO: function calls on var
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckAssert::inSameScope(const Token* returnTok, const Token* assignTok)
|
bool CheckAssert::inSameScope(const Token* returnTok, const Token* assignTok)
|
||||||
|
|
|
@ -183,7 +183,7 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
check("void f(int a, int b) {\n"
|
check("void f(int a, int b) {\n"
|
||||||
" assert(a == 2 && b = 1);\n"
|
" assert(a == 2 && (b = 1));\n"
|
||||||
" return a;\n"
|
" return a;\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
);
|
);
|
||||||
|
@ -220,6 +220,13 @@ private:
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Assert statement modifies 'a'.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (warning) Assert statement modifies 'a'.\n", errout.str());
|
||||||
|
|
||||||
|
check("void f() {\n"
|
||||||
|
" int a = 0;\n"
|
||||||
|
" assert(--a);\n"
|
||||||
|
" return a;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:3]: (warning) Assert statement modifies 'a'.\n", errout.str());
|
||||||
|
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
" assert(std::all_of(first, last, []() {\n"
|
" assert(std::all_of(first, last, []() {\n"
|
||||||
" auto tmp = x.someValue();\n"
|
" auto tmp = x.someValue();\n"
|
||||||
|
|
Loading…
Reference in New Issue