diff --git a/lib/checkother.cpp b/lib/checkother.cpp index b9dbc4e9b..cb340b7ec 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2054,11 +2054,12 @@ void CheckOther::checkMisusedScopedObject() const SymbolDatabase * const symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope * scope : symbolDatabase->functionScopes) { for (const Token *tok = scope->bodyStart; tok && tok != scope->bodyEnd; tok = tok->next()) { - if ((tok->next()->type() || (tok->next()->function() && tok->next()->function()->isConstructor())) // TODO: The rhs of || should be removed; It is a workaround for a symboldatabase bug - && Token::Match(tok, "[;{}] %name% (") - && Token::Match(tok->linkAt(2), ") ; !!}") + if ((tok->next()->type() || tok->next()->isStandardType() || (tok->next()->function() && tok->next()->function()->isConstructor())) // TODO: The rhs of || should be removed; It is a workaround for a symboldatabase bug + && Token::Match(tok, "[;{}] %name% (|{") + && Token::Match(tok->linkAt(2), ")|} ; !!}") && (!tok->next()->function() || // is not a function on this scope - tok->next()->function()->isConstructor())) { // or is function in this scope and it's a ctor + tok->next()->function()->isConstructor()) // or is function in this scope and it's a ctor + && (!tok->tokAt(2)->astOperand2() || isConstStatement(tok->tokAt(2)->astOperand2(), mTokenizer->isCPP()))) { tok = tok->next(); misusedScopeObjectError(tok, tok->str()); tok = tok->next(); diff --git a/test/cfg/windows.cpp b/test/cfg/windows.cpp index 5bf27cbd2..c4d6424ff 100644 --- a/test/cfg/windows.cpp +++ b/test/cfg/windows.cpp @@ -15,6 +15,7 @@ #include #include #include +#include int stringCompare_mbscmp(const unsigned char *string1, const unsigned char *string2) { @@ -1102,3 +1103,11 @@ public: IMPLEMENT_DYNAMIC(MyClass, CObject) IMPLEMENT_DYNCREATE(MyClass, CObject) IMPLEMENT_SERIAL(MyClass,CObject, 42) + +void invalidPrintfArgType_StructMember(double d) { // #9672 + typedef struct { CString st; } my_struct_t; + + my_struct_t my_struct; + // cppcheck-suppress invalidPrintfArgType_sint + my_struct.st.Format("%d", d); +} \ No newline at end of file diff --git a/test/testother.cpp b/test/testother.cpp index 0f57208ab..80c74ea94 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -139,6 +139,7 @@ private: TEST_CASE(testMisusedScopeObjectDoesNotPickNestedClass); TEST_CASE(testMisusedScopeObjectInConstructor); TEST_CASE(testMisusedScopeObjectNoCodeAfter); + TEST_CASE(testMisusedScopeObjectStandardType); TEST_CASE(trac2071); TEST_CASE(trac2084); TEST_CASE(trac3693); @@ -5031,6 +5032,26 @@ private: ASSERT_EQUALS("", errout.str()); } + void testMisusedScopeObjectStandardType() { + check("int g();\n" + "void f(int i) {\n" + " int();\n" + " int(0);\n" + " int( g() );\n" // don't warn + " int{};\n" + " int{ 0 };\n" + " int{ i };\n" + " int{ g() };\n" // don't warn + " g();\n" + "}\n", "test.cpp"); + ASSERT_EQUALS("[test.cpp:3]: (style) Instance of 'int' object is destroyed immediately.\n" + "[test.cpp:4]: (style) Instance of 'int' object is destroyed immediately.\n" + "[test.cpp:6]: (style) Instance of 'int' object is destroyed immediately.\n" + "[test.cpp:7]: (style) Instance of 'int' object is destroyed immediately.\n" + "[test.cpp:8]: (style) Instance of 'int' object is destroyed immediately.\n", + errout.str()); + } + void trac2084() { check("void f()\n" "{\n"