Fixed #4723 (False positive: Pure virtual call within conditional clause)
This commit is contained in:
parent
44d86e97c0
commit
445d08d082
|
@ -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 ||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue