From 9e6ea07c1412951a57c279900cc076317a7d2b0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 4 Feb 2010 21:49:58 +0100 Subject: [PATCH] CheckClass::noMemset: Refactoring so it handles more complex std template types --- lib/checkclass.cpp | 47 ++++++++++++++++++++++++++++++++++++++++------ test/testclass.cpp | 10 ++++++++++ 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 72483ad47..ed62198f5 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -752,16 +752,51 @@ void CheckClass::noMemset() if (tstruct->str() == "}") break; - if (Token::Match(tstruct, "std :: %type% %var% ;")) + // struct with function? skip function body.. + if (Token::simpleMatch(tstruct, ") {")) { - memsetStructError(tok, tok->str(), tstruct->strAt(2)); - break; + tstruct = tstruct->next()->link(); + if (!tstruct) + break; } - if (Token::Match(tstruct, "std :: %type% < %type% *| > %var% ;")) + // before a statement there must be either: + // * private:|protected:|public: + // * { } ; + if (Token::Match(tstruct, "[;{}]") || + tstruct->str().find(":") != std::string::npos) { - memsetStructError(tok, tok->str(), tstruct->strAt(2)); - break; + if (Token::Match(tstruct->next(), "std :: %type% %var% ;")) + memsetStructError(tok, tok->str(), tstruct->strAt(3)); + + else if (Token::Match(tstruct->next(), "std :: %type% < ")) + { + // backup the type + const std::string typestr(tstruct->strAt(3)); + + // check if it's a pointer variable.. + unsigned int level = 0; + while (0 != (tstruct = tstruct->next())) + { + if (tstruct->str() == "<") + ++level; + else if (tstruct->str() == ">") + { + if (level <= 1) + break; + --level; + } + else if (tstruct->str() == "(") + tstruct = tstruct->link(); + } + + if (!tstruct) + break; + + // found error => report + if (Token::Match(tstruct, "> %var% ;")) + memsetStructError(tok, tok->str(), typestr); + } } } } diff --git a/test/testclass.cpp b/test/testclass.cpp index 6cced2496..6351e6f6a 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -1493,6 +1493,16 @@ private: "}"); ASSERT_EQUALS("[test.cpp:7]: (error) Using 'memset' on struct that contains a 'std::vector'\n", errout.str()); + checkNoMemset("struct A\n" + "{ std::vector< std::vector > ints; }\n" + "\n" + "void f()\n" + "{\n" + " A a;\n" + " memset(a, 0, sizeof(A));\n" + "}"); + ASSERT_EQUALS("[test.cpp:7]: (error) Using 'memset' on struct that contains a 'std::vector'\n", errout.str()); + checkNoMemset("struct A\n" "{ std::vector ints; }\n" "\n"