CheckStl: Modernize the recommendations. string::starts_with is more intuitive than string::compare
This commit is contained in:
parent
a688df0ea1
commit
fe04c15c9e
|
@ -612,6 +612,8 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
|
||||||
mSettings->standards.cpp = Standards::CPP14;
|
mSettings->standards.cpp = Standards::CPP14;
|
||||||
} else if (std::strcmp(argv[i], "--std=c++17") == 0) {
|
} else if (std::strcmp(argv[i], "--std=c++17") == 0) {
|
||||||
mSettings->standards.cpp = Standards::CPP17;
|
mSettings->standards.cpp = Standards::CPP17;
|
||||||
|
} else if (std::strcmp(argv[i], "--std=c++20") == 0) {
|
||||||
|
mSettings->standards.cpp = Standards::CPP20;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output formatter
|
// Output formatter
|
||||||
|
@ -1103,7 +1105,9 @@ void CmdLineParser::printHelp()
|
||||||
" * c++14\n"
|
" * c++14\n"
|
||||||
" C++ code is C++14 compatible\n"
|
" C++ code is C++14 compatible\n"
|
||||||
" * c++17\n"
|
" * c++17\n"
|
||||||
" C++ code is C++17 compatible (default)\n"
|
" C++ code is C++17 compatible\n"
|
||||||
|
" * c++20\n"
|
||||||
|
" C++ code is C++20 compatible (default)\n"
|
||||||
" --suppress=<spec> Suppress warnings that match <spec>. The format of\n"
|
" --suppress=<spec> Suppress warnings that match <spec>. The format of\n"
|
||||||
" <spec> is:\n"
|
" <spec> is:\n"
|
||||||
" [error id]:[filename]:[line]\n"
|
" [error id]:[filename]:[line]\n"
|
||||||
|
|
|
@ -1226,14 +1226,14 @@ void CheckStl::if_find()
|
||||||
|
|
||||||
void CheckStl::if_findError(const Token *tok, bool str)
|
void CheckStl::if_findError(const Token *tok, bool str)
|
||||||
{
|
{
|
||||||
if (str)
|
if (str && mSettings->standards.cpp >= Standards::CPP20)
|
||||||
reportError(tok, Severity::performance, "stlIfStrFind",
|
reportError(tok, Severity::performance, "stlIfStrFind",
|
||||||
"Inefficient usage of string::find() in condition; string::compare() would be faster.\n"
|
"Inefficient usage of string::find() in condition; string::starts_with() would be faster.\n"
|
||||||
"Either inefficient or wrong usage of string::find(). string::compare() will be faster if "
|
"Either inefficient or wrong usage of string::find(). string::starts_with() will be faster if "
|
||||||
"string::find's result is compared with 0, because it will not scan the whole "
|
"string::find's result is compared with 0, because it will not scan the whole "
|
||||||
"string. If your intention is to check that there are no findings in the string, "
|
"string. If your intention is to check that there are no findings in the string, "
|
||||||
"you should compare with std::string::npos.", CWE597, false);
|
"you should compare with std::string::npos.", CWE597, false);
|
||||||
else
|
if (!str)
|
||||||
reportError(tok, Severity::warning, "stlIfFind", "Suspicious condition. The result of find() is an iterator, but it is not properly checked.", CWE398, false);
|
reportError(tok, Severity::warning, "stlIfFind", "Suspicious condition. The result of find() is an iterator, but it is not properly checked.", CWE398, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1396,7 +1396,7 @@ void CheckStl::size()
|
||||||
if (!mSettings->isEnabled(Settings::PERFORMANCE))
|
if (!mSettings->isEnabled(Settings::PERFORMANCE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (mSettings->standards.cpp == Standards::CPP11)
|
if (mSettings->standards.cpp >= Standards::CPP11)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase();
|
const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase();
|
||||||
|
|
|
@ -36,10 +36,10 @@ struct Standards {
|
||||||
enum cstd_t { C89, C99, C11, CLatest=C11 } c;
|
enum cstd_t { C89, C99, C11, CLatest=C11 } c;
|
||||||
|
|
||||||
/** C++ code standard */
|
/** C++ code standard */
|
||||||
enum cppstd_t { CPP03, CPP11, CPP14, CPP17, CPPLatest=CPP17 } cpp;
|
enum cppstd_t { CPP03, CPP11, CPP14, CPP17, CPP20, CPPLatest=CPP20 } cpp;
|
||||||
|
|
||||||
/** This constructor clear all the variables **/
|
/** This constructor clear all the variables **/
|
||||||
Standards() : c(C11), cpp(CPP17) {}
|
Standards() : c(C11), cpp(CPPLatest) {}
|
||||||
|
|
||||||
bool setC(const std::string& str) {
|
bool setC(const std::string& str) {
|
||||||
if (str == "c89" || str == "C89") {
|
if (str == "c89" || str == "C89") {
|
||||||
|
@ -73,6 +73,10 @@ struct Standards {
|
||||||
cpp = CPP17;
|
cpp = CPP17;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (str == "c++20" || str == "C++20") {
|
||||||
|
cpp = CPP20;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -159,7 +159,7 @@ private:
|
||||||
TEST_CASE(findInsert);
|
TEST_CASE(findInsert);
|
||||||
}
|
}
|
||||||
|
|
||||||
void check(const char code[], const bool inconclusive=false, const Standards::cppstd_t cppstandard=Standards::CPP11) {
|
void check(const char code[], const bool inconclusive=false, const Standards::cppstd_t cppstandard=Standards::CPPLatest) {
|
||||||
// Clear the error buffer..
|
// Clear the error buffer..
|
||||||
errout.str("");
|
errout.str("");
|
||||||
|
|
||||||
|
@ -2391,35 +2391,35 @@ private:
|
||||||
"{\n"
|
"{\n"
|
||||||
" if (s.find(\"abc\")) { }\n"
|
" if (s.find(\"abc\")) { }\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (performance) Inefficient usage of string::find() in condition; string::compare() would be faster.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (performance) Inefficient usage of string::find() in condition; string::starts_with() would be faster.\n", errout.str());
|
||||||
|
|
||||||
// error (pointer)
|
// error (pointer)
|
||||||
check("void f(const std::string *s)\n"
|
check("void f(const std::string *s)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" if ((*s).find(\"abc\")) { }\n"
|
" if ((*s).find(\"abc\")) { }\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (performance) Inefficient usage of string::find() in condition; string::compare() would be faster.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (performance) Inefficient usage of string::find() in condition; string::starts_with() would be faster.\n", errout.str());
|
||||||
|
|
||||||
// error (pointer)
|
// error (pointer)
|
||||||
check("void f(const std::string *s)\n"
|
check("void f(const std::string *s)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" if (s->find(\"abc\")) { }\n"
|
" if (s->find(\"abc\")) { }\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (performance) Inefficient usage of string::find() in condition; string::compare() would be faster.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (performance) Inefficient usage of string::find() in condition; string::starts_with() would be faster.\n", errout.str());
|
||||||
|
|
||||||
// error (vector)
|
// error (vector)
|
||||||
check("void f(const std::vector<std::string> &s)\n"
|
check("void f(const std::vector<std::string> &s)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" if (s[0].find(\"abc\")) { }\n"
|
" if (s[0].find(\"abc\")) { }\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (performance) Inefficient usage of string::find() in condition; string::compare() would be faster.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (performance) Inefficient usage of string::find() in condition; string::starts_with() would be faster.\n", errout.str());
|
||||||
|
|
||||||
// #3162
|
// #3162
|
||||||
check("void f(const std::string& s1, const std::string& s2)\n"
|
check("void f(const std::string& s1, const std::string& s2)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" if ((!s1.empty()) && (0 == s1.find(s2))) { }\n"
|
" if ((!s1.empty()) && (0 == s1.find(s2))) { }\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (performance) Inefficient usage of string::find() in condition; string::compare() would be faster.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (performance) Inefficient usage of string::find() in condition; string::starts_with() would be faster.\n", errout.str());
|
||||||
|
|
||||||
// #4102
|
// #4102
|
||||||
check("void f(const std::string &define) {\n"
|
check("void f(const std::string &define) {\n"
|
||||||
|
|
Loading…
Reference in New Issue