Fixed #4937 (false positive: Assert calls a function which may have desired side effects)

This commit is contained in:
Alexander Mai 2013-08-22 06:38:54 +02:00 committed by Daniel Marjamäki
parent 6e536b9e35
commit 986ec42d79
3 changed files with 50 additions and 1 deletions

View File

@ -69,7 +69,10 @@ void CheckAssert::assertWithSideEffects()
if (tok2->type() != Token::eAssignmentOp && tok2->type() != Token::eIncDecOp) continue; if (tok2->type() != Token::eAssignmentOp && tok2->type() != Token::eIncDecOp) continue;
const Variable* var = tok2->previous()->variable(); const Variable* var = tok2->previous()->variable();
if (!var || var->isLocal()) continue; if (!var || var->isLocal()) continue;
if (var->isArgument() &&
(var->isConst() || (!var->isReference() && !var->isPointer())))
// see ticket #4937. Assigning function arguments not passed by reference is ok.
continue;
std::vector<const Token*> returnTokens; // find all return statements std::vector<const Token*> returnTokens; // find all return statements
for (const Token *rt = scope->classStart; rt != scope->classEnd; rt = rt->next()) { for (const Token *rt = scope->classStart; rt != scope->classEnd; rt = rt->next()) {
if (!Token::Match(rt, "return %any%")) continue; if (!Token::Match(rt, "return %any%")) continue;

View File

@ -1610,6 +1610,7 @@ void SymbolDatabase::printVariable(const Variable *var, const char *indent) cons
std::cout << indent << " isMutable: " << (var->isMutable() ? "true" : "false") << std::endl; std::cout << indent << " isMutable: " << (var->isMutable() ? "true" : "false") << std::endl;
std::cout << indent << " isStatic: " << (var->isStatic() ? "true" : "false") << std::endl; std::cout << indent << " isStatic: " << (var->isStatic() ? "true" : "false") << std::endl;
std::cout << indent << " isExtern: " << (var->isExtern() ? "true" : "false") << std::endl; std::cout << indent << " isExtern: " << (var->isExtern() ? "true" : "false") << std::endl;
std::cout << indent << " isLocal: " << (var->isLocal() ? "true" : "false") << std::endl;
std::cout << indent << " isConst: " << (var->isConst() ? "true" : "false") << std::endl; std::cout << indent << " isConst: " << (var->isConst() ? "true" : "false") << std::endl;
std::cout << indent << " isClass: " << (var->isClass() ? "true" : "false") << std::endl; std::cout << indent << " isClass: " << (var->isClass() ? "true" : "false") << std::endl;
std::cout << indent << " isArray: " << (var->isArray() ? "true" : "false") << std::endl; std::cout << indent << " isArray: " << (var->isArray() ? "true" : "false") << std::endl;

View File

@ -89,6 +89,51 @@ private:
"assert(foo() == 3); \n" "assert(foo() == 3); \n"
); );
ASSERT_EQUALS("[test.cpp:6]: (warning) Assert statement calls a function which may have desired side effects: 'foo'.\n", errout.str()); ASSERT_EQUALS("[test.cpp:6]: (warning) Assert statement calls a function which may have desired side effects: 'foo'.\n", errout.str());
// Ticket #4937 "false positive: Assert calls a function which may have desired side effects"
check("struct SquarePack {\n"
" static bool isRank1Or8( Square sq ) {\n"
" sq &= 0x38;\n"
" return sq == 0 || sq == 0x38;\n"
" }\n"
"};\n"
"void foo() {\n"
" assert( !SquarePack::isRank1Or8(push2) );\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("struct SquarePack {\n"
" static bool isRank1Or8( Square &sq ) {\n"
" sq &= 0x38;\n"
" return sq == 0 || sq == 0x38;\n"
" }\n"
"};\n"
"void foo() {\n"
" assert( !SquarePack::isRank1Or8(push2) );\n"
"}\n");
ASSERT_EQUALS("[test.cpp:8]: (warning) Assert statement calls a function which may have desired side effects: 'isRank1Or8'.\n", errout.str());
check("struct SquarePack {\n"
" static bool isRank1Or8( Square *sq ) {\n"
" *sq &= 0x38;\n"
" return *sq == 0 || *sq == 0x38;\n"
" }\n"
"};\n"
"void foo() {\n"
" assert( !SquarePack::isRank1Or8(push2) );\n"
"}\n");
ASSERT_EQUALS("[test.cpp:8]: (warning) Assert statement calls a function which may have desired side effects: 'isRank1Or8'.\n", errout.str());
check("struct SquarePack {\n"
" static bool isRank1Or8( Square *sq ) {\n"
" sq &= 0x38;\n"
" return sq == 0 || sq == 0x38;\n"
" }\n"
"};\n"
"void foo() {\n"
" assert( !SquarePack::isRank1Or8(push2) );\n"
"}\n");
TODO_ASSERT_EQUALS("", "[test.cpp:8]: (warning) Assert statement calls a function which may have desired side effects: 'isRank1Or8'.\n", errout.str());
} }
void assignmentInAssert() { void assignmentInAssert() {