Skip to content

Commit 6791574

Browse files
committed
Fixed cppcheck-opensource#4723 (False positive: Pure virtual call within conditional clause)
conditional clauses directly in constructor/destructor cannot prevent pure virtual function call otherwise this part of the code would never been called
1 parent 32e1831 commit 6791574

2 files changed

Lines changed: 33 additions & 8 deletions

File tree

lib/checkclass.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1996,14 +1996,19 @@ const std::list<const Token *> & CheckClass::callsPureVirtualFunction(const Func
19961996
for (const Token *tok = function.arg->link();
19971997
tok && tok != function.functionScope->classEnd;
19981998
tok = tok->next()) {
1999-
if ((Token::simpleMatch(tok,") {") &&
2000-
tok->link() &&
2001-
Token::Match(tok->link()->previous(),"if|switch")) ||
2002-
Token::simpleMatch(tok,"else {")
2003-
) {
2004-
// Assume pure virtual function call is prevented by "if|else|switch" condition
2005-
tok = tok->linkAt(1);
2006-
continue;
1999+
if (function.type != Function::eConstructor &&
2000+
function.type != Function::eCopyConstructor &&
2001+
function.type != Function::eMoveConstructor &&
2002+
function.type != Function::eDestructor) {
2003+
if ((Token::simpleMatch(tok,") {") &&
2004+
tok->link() &&
2005+
Token::Match(tok->link()->previous(),"if|switch")) ||
2006+
Token::simpleMatch(tok,"else {")
2007+
) {
2008+
// Assume pure virtual function call is prevented by "if|else|switch" condition
2009+
tok = tok->linkAt(1);
2010+
continue;
2011+
}
20072012
}
20082013
const Function * callFunction=tok->function();
20092014
if (!callFunction ||

test/testclass.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5679,6 +5679,26 @@ class TestClass : public TestFixture {
56795679
"A::~A()\n"
56805680
"{nonpure();}\n");
56815681
ASSERT_EQUALS("[test.cpp:10] -> [test.cpp:5] -> [test.cpp:3]: (warning) Call of pure virtual function 'pure' in destructor.\n", errout.str());
5682+
5683+
checkPureVirtualFunctionCall("class A\n"
5684+
"{\n"
5685+
" virtual void pure()=0;\n"
5686+
" A(bool b);\n"
5687+
"};\n"
5688+
"A::A(bool b)\n"
5689+
"{if (b) pure();}\n");
5690+
ASSERT_EQUALS("[test.cpp:7] -> [test.cpp:3]: (warning) Call of pure virtual function 'pure' in constructor.\n", errout.str());
5691+
5692+
checkPureVirtualFunctionCall("class A\n"
5693+
" {\n"
5694+
" virtual void pure()=0; \n"
5695+
" virtual ~A(); \n"
5696+
" int m; \n"
5697+
"};\n"
5698+
"A::~A()\n"
5699+
"{if (b) pure();}\n");
5700+
ASSERT_EQUALS("[test.cpp:8] -> [test.cpp:3]: (warning) Call of pure virtual function 'pure' in destructor.\n", errout.str());
5701+
56825702
}
56835703

56845704
void pureVirtualFunctionCallOtherClass() {

0 commit comments

Comments
 (0)