diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 408031840..fafc78aa1 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -898,7 +898,7 @@ static const Scope* findFunctionOf(const Scope* scope) return 0; } -void CheckClass::noMemset() +void CheckClass::checkMemset() { const std::size_t functions = symbolDatabase->functionScopes.size(); for (std::size_t i = 0; i < functions; ++i) { @@ -949,6 +949,20 @@ void CheckClass::noMemset() if (derefs == 0) type = var->typeScope(); + + // TODO: The SymbolDatabase mix up variables in nested structs. + // So we must bailout right now if there are nested structs. + bool bailout = false; + for (const Token *typetok2 = var->typeStartToken(); typetok2 && typetok2 != var->typeEndToken(); typetok2 = typetok2->next()) { + if (typetok2->str() == "::") + bailout = true; + if (typetok2->str() == "{") { + bailout = false; + break; + } + } + if (bailout) + continue; } } diff --git a/lib/checkclass.h b/lib/checkclass.h index e455b21e1..6cff648a3 100644 --- a/lib/checkclass.h +++ b/lib/checkclass.h @@ -50,7 +50,7 @@ public: CheckClass checkClass(tokenizer, settings, errorLogger); // can't be a simplified check .. the 'sizeof' is used. - checkClass.noMemset(); + checkClass.checkMemset(); } /** @brief Run checks on the simplified token list */ @@ -93,7 +93,7 @@ public: * It can also overwrite the virtual table. * Important: The checking doesn't work on simplified tokens list. */ - void noMemset(); + void checkMemset(); void checkMemsetType(const Scope *start, const Token *tok, const Scope *type, bool allocation); /** @brief 'operator=' should return something and it should not be const. */ diff --git a/test/testclass.cpp b/test/testclass.cpp index 206a140fe..9a80b9f61 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -2042,7 +2042,7 @@ private: // Check.. CheckClass checkClass(&tokenizer, &settings, this); - checkClass.noMemset(); + checkClass.checkMemset(); } void memsetOnClass() { @@ -2219,7 +2219,7 @@ private: " n1::Fred fred;\n" " memset(&fred, 0, sizeof(fred));\n" "}"); - ASSERT_EQUALS("[test.cpp:10]: (error) Using 'memset' on class that contains a 'std::string'.\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:10]: (error) Using 'memset' on class that contains a 'std::string'.\n", "", errout.str()); checkNoMemset("class A {\n" " virtual ~A() { }\n" @@ -2231,6 +2231,15 @@ private: " memset(arr, 0, N * sizeof(A*));\n" "}"); ASSERT_EQUALS("", errout.str()); + + checkNoMemset("class A {\n" // #5116 - nested class data is mixed in the SymbolDatabase + " std::string s;\n" + " struct B { int x; };\n" + "};\n" + "void f(A::B *b) {\n" + " memset(b,0,4);\n" + "}"); + ASSERT_EQUALS("", errout.str()); } void memsetOnStruct() {