From 896582ce5687acdda7f17754cd52d79afb60386c Mon Sep 17 00:00:00 2001 From: PKEuS Date: Fri, 6 May 2016 17:24:44 +0200 Subject: [PATCH] Fixes for CheckStl::string_c_str(): - Fixed false positive #7480 - Fixed false negative: Show performance message also for non-local objects --- lib/checkstl.cpp | 6 +++++- test/teststl.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index fe3ec215e..b4d990fd0 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -1047,14 +1047,18 @@ void CheckStl::string_c_str() } bool local = false; + bool ptr = false; const Variable* lastVar = nullptr; const Function* lastFunc = nullptr; bool funcStr = false; if (Token::Match(tok2, "%var% .")) { local = isLocal(tok2); + ptr = tok2->variable() && tok2->variable()->isPointer(); } while (tok2) { if (Token::Match(tok2, "%var% .|::")) { + if (ptr) + local = false; lastVar = tok2->variable(); tok2 = tok2->tokAt(2); } else if (Token::Match(tok2, "%name% (") && Token::simpleMatch(tok2->linkAt(1), ") .")) { @@ -1067,7 +1071,7 @@ void CheckStl::string_c_str() } if (Token::Match(tok2, "c_str|data ( ) ;")) { - if (local && lastVar && lastVar->isStlStringType()) + if ((local || returnType != charPtr) && lastVar && lastVar->isStlStringType()) err = true; else if (funcStr && lastVar && lastVar->isStlType(stl_string_stream)) err = true; diff --git a/test/teststl.cpp b/test/teststl.cpp index d6aad2d9c..459401a82 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -2303,6 +2303,34 @@ private: " return String::Format(\"%s:\", name).c_str();\n" "}"); ASSERT_EQUALS("", errout.str()); + + // #7480 + check("struct InternalMapInfo {\n" + " std::string author;\n" + "};\n" + "const char* GetMapAuthor(int index) {\n" + " const InternalMapInfo* mapInfo = &internal_getMapInfo;\n" + " return mapInfo->author.c_str();\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check("struct InternalMapInfo {\n" + " std::string author;\n" + "};\n" + "std::string GetMapAuthor(int index) {\n" + " const InternalMapInfo* mapInfo = &internal_getMapInfo;\n" + " return mapInfo->author.c_str();\n" + "}"); + ASSERT_EQUALS("[test.cpp:6]: (performance) Returning the result of c_str() in a function that returns std::string is slow and redundant.\n", errout.str()); + + check("struct InternalMapInfo {\n" + " std::string author;\n" + "};\n" + "const char* GetMapAuthor(int index) {\n" + " const InternalMapInfo mapInfo = internal_getMapInfo;\n" + " return mapInfo.author.c_str();\n" + "}"); + ASSERT_EQUALS("[test.cpp:6]: (error) Dangerous usage of c_str(). The value returned by c_str() is invalid after this call.\n", errout.str()); } void autoPointer() {