Fix FP constParameter with std::map (#3823)

This commit is contained in:
chrchr-github 2022-02-11 19:40:11 +01:00 committed by GitHub
parent 04b2a6f1c5
commit 5f3ddabd56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 26 additions and 9 deletions

View File

@ -465,7 +465,7 @@ $(libcppdir)/checkmemoryleak.o: lib/checkmemoryleak.cpp lib/astutils.h lib/check
$(libcppdir)/checknullpointer.o: lib/checknullpointer.cpp lib/astutils.h lib/check.h lib/checknullpointer.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h $(libcppdir)/checknullpointer.o: lib/checknullpointer.cpp lib/astutils.h lib/check.h lib/checknullpointer.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/checknullpointer.o $(libcppdir)/checknullpointer.cpp $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/checknullpointer.o $(libcppdir)/checknullpointer.cpp
$(libcppdir)/checkother.o: lib/checkother.cpp lib/astutils.h lib/check.h lib/checkother.h lib/checkuninitvar.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h $(libcppdir)/checkother.o: lib/checkother.cpp lib/astutils.h lib/check.h lib/checkclass.h lib/checkother.h lib/checkuninitvar.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/checkother.o $(libcppdir)/checkother.cpp $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/checkother.o $(libcppdir)/checkother.cpp
$(libcppdir)/checkpostfixoperator.o: lib/checkpostfixoperator.cpp lib/check.h lib/checkpostfixoperator.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h $(libcppdir)/checkpostfixoperator.o: lib/checkpostfixoperator.cpp lib/check.h lib/checkpostfixoperator.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h

View File

@ -2131,9 +2131,7 @@ bool CheckClass::isConstMemberFunc(const Scope *scope, const Token *tok) const
return false; return false;
} }
const std::set<std::string> CheckClass::stl_containers_not_const = { "map", "unordered_map" };
// The container contains the STL types whose operator[] is not a const.
static const std::set<std::string> stl_containers_not_const = { "map", "unordered_map" };
bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, bool& memberAccessed) const bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, bool& memberAccessed) const
{ {

View File

@ -188,6 +188,9 @@ public:
/** @brief Analyse all file infos for all TU */ /** @brief Analyse all file infos for all TU */
bool analyseWholeProgram(const CTU::FileInfo *ctu, const std::list<Check::FileInfo*> &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; bool analyseWholeProgram(const CTU::FileInfo *ctu, const std::list<Check::FileInfo*> &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override;
/** @brief Set of the STL types whose operator[] is not const */
static const std::set<std::string> stl_containers_not_const;
private: private:
const SymbolDatabase *mSymbolDatabase; const SymbolDatabase *mSymbolDatabase;

View File

@ -32,6 +32,7 @@
#include "valueflow.h" #include "valueflow.h"
#include "checkuninitvar.h" // CheckUninitVar::isVariableUsage #include "checkuninitvar.h" // CheckUninitVar::isVariableUsage
#include "checkclass.h" // CheckClass::stl_containers_not_const
#include <algorithm> // find_if() #include <algorithm> // find_if()
#include <cctype> #include <cctype>
@ -1502,12 +1503,22 @@ void CheckOther::checkConstVariable()
if (var->isReference()) { if (var->isReference()) {
bool callNonConstMethod = false; bool callNonConstMethod = false;
for (const Token* tok = var->nameToken(); tok != scope->bodyEnd && tok != nullptr; tok = tok->next()) { for (const Token* tok = var->nameToken(); tok != scope->bodyEnd && tok != nullptr; tok = tok->next()) {
if (tok->variable() == var && Token::Match(tok, "%var% . * ( & %name% ::")) { if (tok->variable() == var) {
const Token *ftok = tok->linkAt(3)->previous(); if (Token::Match(tok, "%var% . * ( & %name% ::")) {
const Token* ftok = tok->linkAt(3)->previous();
if (!ftok->function() || !ftok->function()->isConst()) if (!ftok->function() || !ftok->function()->isConst())
callNonConstMethod = true; callNonConstMethod = true;
break; break;
} }
if (var->isStlType() && Token::Match(tok, "%var% [")) { // containers whose operator[] is non-const
const Token* typeTok = var->typeStartToken() ? var->typeStartToken()->tokAt(2) : nullptr;
const auto& notConst = CheckClass::stl_containers_not_const;
if (typeTok && notConst.find(typeTok->str()) != notConst.end()) {
callNonConstMethod = true;
break;
}
}
}
} }
if (callNonConstMethod) if (callNonConstMethod)
continue; continue;

View File

@ -2746,6 +2746,11 @@ private:
" T& g(C& c, T C::*f) { return c.*f; }\n" " T& g(C& c, T C::*f) { return c.*f; }\n"
"};\n"); "};\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f(std::map<int, int>& m) {\n"
" std::cout << m[0] << std::endl;\n"
"};\n");
ASSERT_EQUALS("", errout.str());
} }
void constParameterCallback() { void constParameterCallback() {