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 // 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)

View File

@ -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"