Skip to content

Commit 896582c

Browse files
committed
Fixes for CheckStl::string_c_str():
- Fixed false positive danmar#7480 - Fixed false negative: Show performance message also for non-local objects
1 parent 3366a74 commit 896582c

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

lib/checkstl.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1047,14 +1047,18 @@ void CheckStl::string_c_str()
10471047
}
10481048

10491049
bool local = false;
1050+
bool ptr = false;
10501051
const Variable* lastVar = nullptr;
10511052
const Function* lastFunc = nullptr;
10521053
bool funcStr = false;
10531054
if (Token::Match(tok2, "%var% .")) {
10541055
local = isLocal(tok2);
1056+
ptr = tok2->variable() && tok2->variable()->isPointer();
10551057
}
10561058
while (tok2) {
10571059
if (Token::Match(tok2, "%var% .|::")) {
1060+
if (ptr)
1061+
local = false;
10581062
lastVar = tok2->variable();
10591063
tok2 = tok2->tokAt(2);
10601064
} else if (Token::Match(tok2, "%name% (") && Token::simpleMatch(tok2->linkAt(1), ") .")) {
@@ -1067,7 +1071,7 @@ void CheckStl::string_c_str()
10671071
}
10681072

10691073
if (Token::Match(tok2, "c_str|data ( ) ;")) {
1070-
if (local && lastVar && lastVar->isStlStringType())
1074+
if ((local || returnType != charPtr) && lastVar && lastVar->isStlStringType())
10711075
err = true;
10721076
else if (funcStr && lastVar && lastVar->isStlType(stl_string_stream))
10731077
err = true;

test/teststl.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2303,6 +2303,34 @@ class TestStl : public TestFixture {
23032303
" return String::Format(\"%s:\", name).c_str();\n"
23042304
"}");
23052305
ASSERT_EQUALS("", errout.str());
2306+
2307+
// #7480
2308+
check("struct InternalMapInfo {\n"
2309+
" std::string author;\n"
2310+
"};\n"
2311+
"const char* GetMapAuthor(int index) {\n"
2312+
" const InternalMapInfo* mapInfo = &internal_getMapInfo;\n"
2313+
" return mapInfo->author.c_str();\n"
2314+
"}");
2315+
ASSERT_EQUALS("", errout.str());
2316+
2317+
check("struct InternalMapInfo {\n"
2318+
" std::string author;\n"
2319+
"};\n"
2320+
"std::string GetMapAuthor(int index) {\n"
2321+
" const InternalMapInfo* mapInfo = &internal_getMapInfo;\n"
2322+
" return mapInfo->author.c_str();\n"
2323+
"}");
2324+
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());
2325+
2326+
check("struct InternalMapInfo {\n"
2327+
" std::string author;\n"
2328+
"};\n"
2329+
"const char* GetMapAuthor(int index) {\n"
2330+
" const InternalMapInfo mapInfo = internal_getMapInfo;\n"
2331+
" return mapInfo.author.c_str();\n"
2332+
"}");
2333+
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());
23062334
}
23072335

23082336
void autoPointer() {

0 commit comments

Comments
 (0)