From 79f091c59a3664af6b22563d4b692ef93a82931a Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 21 Jul 2022 22:15:16 +0200 Subject: [PATCH] Fix uselessCallsConstructor TODOs (#4299) * Fix uselessCallsConstructor TODOs * Format --- lib/checkstl.cpp | 16 +++++++++++++--- test/teststl.cpp | 17 +++++++++++------ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 793523c24..fbdbc8661 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -2175,9 +2175,19 @@ void CheckStl::uselessCalls() uselessCallsEmptyError(tok->next()); else if (Token::Match(tok, "[{};] std :: remove|remove_if|unique (") && tok->tokAt(5)->nextArgument()) uselessCallsRemoveError(tok->next(), tok->strAt(3)); - else if (printPerformance && Token::Match(tok, "%var% = { %var% . begin ( ) ,") && - tok->valueType() && tok->valueType()->type == ValueType::CONTAINER && tok->varId() == tok->tokAt(3)->varId()) { - uselessCallsConstructorError(tok); + else if (printPerformance && tok->valueType() && tok->valueType()->type == ValueType::CONTAINER) { + if (Token::Match(tok, "%var% = { %var% . begin ( ) ,") && tok->varId() == tok->tokAt(3)->varId()) + uselessCallsConstructorError(tok); + else if (const Variable* var = tok->variable()) { + std::string pattern = "%var% = "; + for (const Token* t = var->typeStartToken(); t != var->typeEndToken()->next(); t = t->next()) { + pattern += t->str(); + pattern += ' '; + } + pattern += "{|( %varid% . begin ( ) ,"; + if (Token::Match(tok, pattern.c_str(), tok->varId())) + uselessCallsConstructorError(tok); + } } } } diff --git a/test/teststl.cpp b/test/teststl.cpp index 2ac0aa57e..12b91143f 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -4202,17 +4202,22 @@ private: " s = std::string{ s.begin(), s.begin() + end };\n" " return s;\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:2]: (performance) Inefficient constructor call: container 's' is assigned a partial copy of itself. Use erase() or resize() instead.\n", - "", - errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (performance) Inefficient constructor call: container 's' is assigned a partial copy of itself. Use erase() or resize() instead.\n", + errout.str()); check("std::string f(std::string s, std::size_t end) {\n" " s = std::string(s.begin(), s.begin() + end);\n" " return s;\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:2]: (performance) Inefficient constructor call: container 's' is assigned a partial copy of itself. Use erase() or resize() instead.\n", - "", - errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (performance) Inefficient constructor call: container 's' is assigned a partial copy of itself. Use erase() or resize() instead.\n", + errout.str()); + + check("std::vector f(std::vector v, std::size_t end) {\n" + " v = std::vector(v.begin(), v.begin() + end);\n" + " return v;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2]: (performance) Inefficient constructor call: container 'v' is assigned a partial copy of itself. Use erase() or resize() instead.\n", + errout.str()); } void stabilityOfChecks() {