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:
Carl Michael Grüner Monzón 2020-04-18 01:26:24 -06:00 committed by GitHub
parent 453a69dd8c
commit 7c93f51885
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 9 deletions

View File

@ -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
void CheckAssert::checkVariableAssignment(const Token* assignTok, const Scope *assertionScope)
{
const Variable* prevVar = assignTok->previous()->variable();
if (!prevVar)
if (!assignTok->isAssignmentOp() && assignTok->tokType() != Token::eIncDecOp)
return;
const Variable* var = assignTok->astOperand1()->variable();
if (!var)
return;
// Variable declared in inner scope in assert => don't warn
if (assertionScope != prevVar->scope()) {
const Scope *s = prevVar->scope();
if (assertionScope != var->scope()) {
const Scope *s = var->scope();
while (s && s != assertionScope)
s = s->nestedIn;
if (s == assertionScope)
@ -135,12 +138,12 @@ void CheckAssert::checkVariableAssignment(const Token* assignTok, const Scope *a
// assignment
if (assignTok->isAssignmentOp() || assignTok->tokType() == Token::eIncDecOp) {
if (prevVar->isConst())
if (var->isConst()) {
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)

View File

@ -183,7 +183,7 @@ private:
ASSERT_EQUALS("", errout.str());
check("void f(int a, int b) {\n"
" assert(a == 2 && b = 1);\n"
" assert(a == 2 && (b = 1));\n"
" return a;\n"
"}\n"
);
@ -220,6 +220,13 @@ private:
"}\n");
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"
" assert(std::all_of(first, last, []() {\n"
" auto tmp = x.someValue();\n"