From ba3833c692eb408369e20d20b010405b39b45c41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 29 Nov 2012 07:10:56 +0100 Subject: [PATCH] Fixed #3678 (stlcstrReturn for classes which don't provide a std::string) --- lib/checkstl.cpp | 15 ++++++++++++--- test/teststl.cpp | 6 ++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index ccab39baa..ffca82622 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -1196,7 +1196,7 @@ void CheckStl::string_c_str() tok2 = tok2->previous(); if (tok2 && Token::simpleMatch(tok2->tokAt(-4), ". c_str ( )")) { const Variable* var = symbolDatabase->getVariableFromVarId(tok2->tokAt(-5)->varId()); - if (var && Token::Match(var->typeStartToken(), "const| std :: string|wstring")) + if (var && Token::Match(var->typeStartToken(), "const| std ::")) string_c_strParam(tok, i->second); } } @@ -1238,8 +1238,17 @@ void CheckStl::string_c_str() else if ((returnType == stdString || returnType == stdStringConstRef) && _settings->isEnabled("performance")) { if (tok->str() == "return") { const Token* tok2 = Token::findsimplematch(tok->next(), ";"); - if (Token::simpleMatch(tok2->tokAt(-4), ". c_str ( )")) - string_c_strReturn(tok); + if (Token::simpleMatch(tok2->tokAt(-4), ". c_str ( )")) { + tok2 = tok2->tokAt(-5); + if (tok2->isName()) { // return var.c_str(); => check if var is a std type + const Variable* var = symbolDatabase->getVariableFromVarId(tok2->varId()); + if (var && Token::Match(var->typeStartToken(), "const| std ::")) + string_c_strReturn(tok); + } else { + // TODO: determine if a error should be written or not + string_c_strReturn(tok); + } + } } } } diff --git a/test/teststl.cpp b/test/teststl.cpp index 3d45eb4cc..0c2f7510b 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -1769,6 +1769,12 @@ private: "}"); ASSERT_EQUALS("", errout.str()); + check("std::string get_msg() {\n" // #3678 + " MyStringClass errmsg;\n" + " return errmsg.c_str();\n" + "}"); + ASSERT_EQUALS("", errout.str()); + check("void Foo1(const std::string& str) {}\n" "void Foo2(char* c, const std::string str) {}\n"