From a22a77c1fc0f5dbf6db88de803e240fd23475a19 Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Fri, 3 Apr 2020 06:16:57 -0500 Subject: [PATCH] Use library config for unstable containers instead of hardcoded values (#2585) * Use library config for unstable containers instead of hardcoded values * Fix xml validation --- cfg/boost.cfg | 4 +++- cfg/cppcheck-cfg.rng | 13 +++++++++++++ cfg/std.cfg | 10 ++++++++-- lib/checkstl.cpp | 29 ++++++++++++++++++++++++++--- lib/library.cpp | 9 +++++++++ lib/library.h | 6 +++++- 6 files changed, 64 insertions(+), 7 deletions(-) diff --git a/cfg/boost.cfg b/cfg/boost.cfg index 7f29e1889..87f7493df 100644 --- a/cfg/boost.cfg +++ b/cfg/boost.cfg @@ -69,7 +69,9 @@ - + + + diff --git a/cfg/cppcheck-cfg.rng b/cfg/cppcheck-cfg.rng index a5ccd4ae2..d393a6383 100644 --- a/cfg/cppcheck-cfg.rng +++ b/cfg/cppcheck-cfg.rng @@ -391,6 +391,19 @@ std-like + + + + + + + erase + insert + + + + + diff --git a/cfg/std.cfg b/cfg/std.cfg index e05ab521f..288d4ea3c 100644 --- a/cfg/std.cfg +++ b/cfg/std.cfg @@ -7871,7 +7871,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init - + @@ -7889,6 +7889,12 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init + + + + + + @@ -7987,7 +7993,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init - + diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index e43b21614..e88020af8 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -710,12 +710,35 @@ void CheckStl::mismatchingContainers() static bool isInvalidMethod(const Token * tok) { - if (Token::Match(tok->next(), ". assign|clear")) + if (Token::Match(tok->next(), ". assign|clear|swap")) return true; if (Token::Match(tok->next(), "%assign%")) return true; - if (isVector(tok) && Token::Match(tok->next(), ". insert|emplace|emplace_back|push_back|erase|pop_back|reserve (")) - return true; + if (const Library::Container * c = tok->valueType()->container) { + Library::Container::Action action = c->getAction(tok->strAt(2)); + if (c->unstableErase) { + if (action == Library::Container::Action::ERASE) + return true; + } + if (c->unstableInsert) { + if (action == Library::Container::Action::RESIZE) + return true; + if (action == Library::Container::Action::CLEAR) + return true; + if (action == Library::Container::Action::PUSH) + return true; + if (action == Library::Container::Action::POP) + return true; + if (action == Library::Container::Action::INSERT) + return true; + if (action == Library::Container::Action::CHANGE) + return true; + if (action == Library::Container::Action::CHANGE_INTERNAL) + return true; + if (Token::Match(tok->next(), ". insert|emplace")) + return true; + } + } return false; } diff --git a/lib/library.cpp b/lib/library.cpp index 44f9c078f..ce7bae980 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -31,6 +31,7 @@ #include #include #include +#include static std::vector getnames(const char *names) { @@ -500,6 +501,14 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) const char* const associative = containerNode->Attribute("associative"); if (associative) container.stdAssociativeLike = std::string(associative) == "std-like"; + const char* const unstable = containerNode->Attribute("unstable"); + if (unstable) { + std::string unstableType = unstable; + if (unstableType.find("erase") != std::string::npos) + container.unstableErase = true; + if (unstableType.find("insert") != std::string::npos) + container.unstableInsert = true; + } } else unknown_elements.insert(containerNodeName); } diff --git a/lib/library.h b/lib/library.h index 75416b2b8..d64607c80 100644 --- a/lib/library.h +++ b/lib/library.h @@ -197,7 +197,9 @@ public: stdStringLike(false), stdAssociativeLike(false), opLessAllowed(true), - hasInitializerListConstructor(false) { + hasInitializerListConstructor(false), + unstableErase(false), + unstableInsert(false) { } enum class Action { @@ -221,6 +223,8 @@ public: bool stdAssociativeLike; bool opLessAllowed; bool hasInitializerListConstructor; + bool unstableErase; + bool unstableInsert; Action getAction(const std::string& function) const { const std::map::const_iterator i = functions.find(function);