Fixed #4723 (False positive: Pure virtual call within conditional clause)

This commit is contained in:
Frank Zingsheim 2013-09-26 17:25:16 +02:00
parent 44d86e97c0
commit 445d08d082
2 changed files with 50 additions and 1 deletions

View File

@ -1994,8 +1994,17 @@ const std::list<const Token *> & CheckClass::callsPureVirtualFunction(const Func
if (found.second) {
if (function.hasBody) {
for (const Token *tok = function.arg->link();
tok != function.functionScope->classEnd;
tok && tok != function.functionScope->classEnd;
tok = tok->next()) {
if ((Token::simpleMatch(tok,") {") &&
tok->link() &&
Token::Match(tok->link()->previous(),"if|switch")) ||
Token::simpleMatch(tok,"else {")
) {
// Assume pure virtual function call is prevented by "if|else|switch" condition
tok = tok->linkAt(1);
continue;
}
const Function * callFunction=tok->function();
if (!callFunction ||
function.nestedIn != callFunction->nestedIn ||

View File

@ -176,6 +176,7 @@ private:
TEST_CASE(pureVirtualFunctionCall);
TEST_CASE(pureVirtualFunctionCallOtherClass);
TEST_CASE(pureVirtualFunctionCallWithBody);
TEST_CASE(pureVirtualFunctionCallPrevented);
TEST_CASE(duplInheritedMembers);
}
@ -5731,6 +5732,45 @@ private:
}
void pureVirtualFunctionCallPrevented() {
checkPureVirtualFunctionCall("class A\n"
" {\n"
" virtual void pure()=0;\n"
" void nonpure(bool bCallPure)\n"
" { if (bCallPure) pure();}\n"
" A(); \n"
"};\n"
"A::A()\n"
"{nonpure(false);}\n");
ASSERT_EQUALS("", errout.str());
checkPureVirtualFunctionCall("class A\n"
" {\n"
" virtual void pure()=0;\n"
" void nonpure(bool bCallPure)\n"
" { if (!bCallPure) ; else pure();}\n"
" A(); \n"
"};\n"
"A::A()\n"
"{nonpure(false);}\n");
ASSERT_EQUALS("", errout.str());
checkPureVirtualFunctionCall("class A\n"
" {\n"
" virtual void pure()=0;\n"
" void nonpure(bool bCallPure)\n"
" {\n"
" switch (bCallPure) {\n"
" case true: pure(); break;\n"
" }\n"
" }\n"
" A(); \n"
"};\n"
"A::A()\n"
"{nonpure(false);}\n");
ASSERT_EQUALS("", errout.str());
}
};
REGISTER_TEST(TestClass)