diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 3b0b49083..cbd90027b 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -1593,8 +1593,19 @@ void CheckStl::checkFindInsert() void CheckStl::checkFindInsertError(const Token *tok) { + std::string replaceExpr; + if (tok && Token::simpleMatch(tok->astParent(), "=") && tok == tok->astParent()->astOperand2() && Token::simpleMatch(tok->astParent()->astOperand1(), "[")) { + replaceExpr = " Instead of '" + tok->astParent()->expressionString() + "' consider using '" + + tok->astParent()->astOperand1()->astOperand1()->expressionString() + + (mSettings->standards.cpp < Standards::CPP17 ? ".insert(" : ".emplace(") + + tok->astParent()->astOperand1()->astOperand2()->expressionString() + + ", " + + tok->expressionString() + + ");'."; + } + reportError( - tok, Severity::performance, "stlFindInsert", "Searching before insertion is not necessary.", CWE398, Certainty::normal); + tok, Severity::performance, "stlFindInsert", "Searching before insertion is not necessary." + replaceExpr, CWE398, Certainty::normal); } /** diff --git a/test/teststl.cpp b/test/teststl.cpp index 61ddd45f2..444a2abe2 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -5152,6 +5152,17 @@ private: check(code, true, Standards::CPP17); ASSERT_EQUALS("[test.cpp:3]: (performance) Searching before insertion is not necessary.\n", errout.str()); } + + check("void foo() {\n" + " std::map x;\n" + " int data = 0;\n" + " for(int i=0; i<10; ++i) {\n" + " data += 123;\n" + " if(x.find(5) == x.end())\n" + " x[5] = data;\n" + " }\n" + "}"); + ASSERT_EQUALS("[test.cpp:7]: (performance) Searching before insertion is not necessary. Instead of 'x[5]=data' consider using 'x.emplace(5, data);'.\n", errout.str()); } void checkKnownEmptyContainer() {