Use std::unordered_* containers for faster lookups (#3052)

This commit is contained in:
Oliver Stöneberg 2021-01-16 13:52:09 +01:00 committed by GitHub
parent 76f759fcc4
commit 7aa85aa408
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 35 additions and 32 deletions

View File

@ -112,7 +112,7 @@ struct Filepointer {
};
namespace {
const std::set<std::string> whitelist = { "clearerr", "feof", "ferror", "fgetpos", "ftell", "setbuf", "setvbuf", "ungetc", "ungetwc" };
const std::unordered_set<std::string> whitelist = { "clearerr", "feof", "ferror", "fgetpos", "ftell", "setbuf", "setvbuf", "ungetc", "ungetwc" };
}
void CheckIO::checkFileUsage()

View File

@ -54,7 +54,7 @@ static const CWE CWE772(772U); // Missing Release of Resource after Effective L
* This list contains function names with const parameters e.g.: atof(const char *)
* TODO: This list should be replaced by <leak-ignore/> in .cfg files.
*/
static const std::set<std::string> call_func_white_list = {
static const std::unordered_set<std::string> call_func_white_list = {
"_open", "_wopen", "access", "adjtime", "asctime_r", "asprintf", "chdir", "chmod", "chown"
, "creat", "ctime_r", "execl", "execle", "execlp", "execv", "execve", "fchmod", "fcntl"
, "fdatasync", "fclose", "flock", "fmemopen", "fnmatch", "fopen", "fopencookie", "for", "free"

View File

@ -1008,7 +1008,7 @@ bool Library::isnullargbad(const Token *ftok, int argnr) const
if (!arg) {
// scan format string argument should not be null
const std::string funcname = getFunctionName(ftok);
const std::map<std::string, Function>::const_iterator it = functions.find(funcname);
const std::unordered_map<std::string, Function>::const_iterator it = functions.find(funcname);
if (it != functions.cend() && it->second.formatstr && it->second.formatstr_scan)
return true;
}
@ -1021,7 +1021,7 @@ bool Library::isuninitargbad(const Token *ftok, int argnr, int indirect, bool *h
if (!arg) {
// non-scan format string argument should not be uninitialized
const std::string funcname = getFunctionName(ftok);
const std::map<std::string, Function>::const_iterator it = functions.find(funcname);
const std::unordered_map<std::string, Function>::const_iterator it = functions.find(funcname);
if (it != functions.cend() && it->second.formatstr && !it->second.formatstr_scan)
return true;
}
@ -1078,7 +1078,7 @@ const Library::ArgumentChecks * Library::getarg(const Token *ftok, int argnr) co
{
if (isNotLibraryFunction(ftok))
return nullptr;
const std::map<std::string, Function>::const_iterator it1 = functions.find(getFunctionName(ftok));
const std::unordered_map<std::string, Function>::const_iterator it1 = functions.find(getFunctionName(ftok));
if (it1 == functions.cend())
return nullptr;
const std::map<int,ArgumentChecks>::const_iterator it2 = it1->second.argumentChecks.find(argnr);
@ -1189,7 +1189,7 @@ bool Library::isNotLibraryFunction(const Token *ftok) const
bool Library::matchArguments(const Token *ftok, const std::string &functionName) const
{
const int callargs = numberOfArguments(ftok);
const std::map<std::string, Function>::const_iterator it = functions.find(functionName);
const std::unordered_map<std::string, Function>::const_iterator it = functions.find(functionName);
if (it == functions.cend())
return (callargs == 0);
int args = 0;
@ -1259,7 +1259,7 @@ bool Library::formatstr_function(const Token* ftok) const
if (isNotLibraryFunction(ftok))
return false;
const std::map<std::string, Function>::const_iterator it = functions.find(getFunctionName(ftok));
const std::unordered_map<std::string, Function>::const_iterator it = functions.find(getFunctionName(ftok));
if (it != functions.cend())
return it->second.formatstr;
return false;
@ -1290,7 +1290,7 @@ Library::UseRetValType Library::getUseRetValType(const Token *ftok) const
{
if (isNotLibraryFunction(ftok))
return Library::UseRetValType::NONE;
const std::map<std::string, Function>::const_iterator it = functions.find(getFunctionName(ftok));
const std::unordered_map<std::string, Function>::const_iterator it = functions.find(getFunctionName(ftok));
if (it != functions.cend())
return it->second.useretval;
return Library::UseRetValType::NONE;
@ -1332,7 +1332,7 @@ const Library::Function *Library::getFunction(const Token *ftok) const
{
if (isNotLibraryFunction(ftok))
return nullptr;
const std::map<std::string, Function>::const_iterator it1 = functions.find(getFunctionName(ftok));
const std::unordered_map<std::string, Function>::const_iterator it1 = functions.find(getFunctionName(ftok));
if (it1 == functions.cend())
return nullptr;
return &it1->second;
@ -1343,7 +1343,7 @@ bool Library::hasminsize(const Token *ftok) const
{
if (isNotLibraryFunction(ftok))
return false;
const std::map<std::string, Function>::const_iterator it1 = functions.find(getFunctionName(ftok));
const std::unordered_map<std::string, Function>::const_iterator it1 = functions.find(getFunctionName(ftok));
if (it1 == functions.cend())
return false;
for (std::map<int, ArgumentChecks>::const_iterator it2 = it1->second.argumentChecks.cbegin(); it2 != it1->second.argumentChecks.cend(); ++it2) {
@ -1372,28 +1372,28 @@ Library::ArgumentChecks::Direction Library::getArgDirection(const Token* ftok, i
bool Library::ignorefunction(const std::string& functionName) const
{
const std::map<std::string, Function>::const_iterator it = functions.find(functionName);
const std::unordered_map<std::string, Function>::const_iterator it = functions.find(functionName);
if (it != functions.cend())
return it->second.ignore;
return false;
}
bool Library::isUse(const std::string& functionName) const
{
const std::map<std::string, Function>::const_iterator it = functions.find(functionName);
const std::unordered_map<std::string, Function>::const_iterator it = functions.find(functionName);
if (it != functions.cend())
return it->second.use;
return false;
}
bool Library::isLeakIgnore(const std::string& functionName) const
{
const std::map<std::string, Function>::const_iterator it = functions.find(functionName);
const std::unordered_map<std::string, Function>::const_iterator it = functions.find(functionName);
if (it != functions.cend())
return it->second.leakignore;
return false;
}
bool Library::isFunctionConst(const std::string& functionName, bool pure) const
{
const std::map<std::string, Function>::const_iterator it = functions.find(functionName);
const std::unordered_map<std::string, Function>::const_iterator it = functions.find(functionName);
if (it != functions.cend())
return pure ? it->second.ispure : it->second.isconst;
return false;
@ -1404,7 +1404,7 @@ bool Library::isFunctionConst(const Token *ftok) const
return true;
if (isNotLibraryFunction(ftok))
return false;
const std::map<std::string, Function>::const_iterator it = functions.find(getFunctionName(ftok));
const std::unordered_map<std::string, Function>::const_iterator it = functions.find(getFunctionName(ftok));
return (it != functions.end() && it->second.isconst);
}

View File

@ -30,6 +30,8 @@
#include <map>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
@ -316,7 +318,7 @@ public:
};
const Function *getFunction(const Token *ftok) const;
std::map<std::string, Function> functions;
std::unordered_map<std::string, Function> functions;
bool isUse(const std::string& functionName) const;
bool isLeakIgnore(const std::string& functionName) const;
bool isFunctionConst(const std::string& functionName, bool pure) const;
@ -422,7 +424,7 @@ public:
std::vector<std::string> defines; // to provide some library defines
std::set<std::string> smartPointers;
std::unordered_set<std::string> smartPointers;
bool isSmartPointer(const Token *tok) const;
struct PodType {
@ -431,7 +433,7 @@ public:
enum class Type { NO, BOOL, CHAR, SHORT, INT, LONG, LONGLONG } stdtype;
};
const struct PodType *podtype(const std::string &name) const {
const std::map<std::string, struct PodType>::const_iterator it = mPodTypes.find(name);
const std::unordered_map<std::string, struct PodType>::const_iterator it = mPodTypes.find(name);
return (it != mPodTypes.end()) ? &(it->second) : nullptr;
}
@ -575,7 +577,7 @@ private:
std::map<std::string, ExportedFunctions> mExporters; // keywords that export variables/functions to libraries (meta-code/macros)
std::map<std::string, std::set<std::string> > mImporters; // keywords that import variables/functions
std::map<std::string, int> mReflection; // invocation of reflection
std::map<std::string, struct PodType> mPodTypes; // pod types
std::unordered_map<std::string, struct PodType> mPodTypes; // pod types
std::map<std::string, PlatformType> mPlatformTypes; // platform independent typedefs
std::map<std::string, Platform> mPlatforms; // platform dependent typedefs
std::map<std::pair<std::string,std::string>, TypeCheck> mTypeChecks;

View File

@ -1308,7 +1308,7 @@ void SymbolDatabase::createSymbolDatabaseEnums()
void SymbolDatabase::createSymbolDatabaseIncompleteVars()
{
const std::set<std::string> cpp20keywords = {
static const std::unordered_set<std::string> cpp20keywords = {
"alignas",
"alignof",
"axiom",
@ -1321,7 +1321,7 @@ void SymbolDatabase::createSymbolDatabaseIncompleteVars()
"reflexpr",
"requires",
};
const std::set<std::string> cppkeywords = {
static const std::unordered_set<std::string> cppkeywords = {
"asm",
"auto",
"catch",
@ -5379,8 +5379,8 @@ namespace {
"register", "return", "short", "signed", "sizeof", "static", "struct", "switch", "typedef", \
"union", "unsigned", "void", "volatile", "while"
const std::set<std::string> c_keywords = { C_KEYWORDS, "restrict" };
const std::set<std::string> cpp_keywords = {
const std::unordered_set<std::string> c_keywords = { C_KEYWORDS, "restrict" };
const std::unordered_set<std::string> cpp_keywords = {
C_KEYWORDS,
"alignas", "alignof", "and", "and_eq", "asm", "bitand", "bitor", "bool", "catch", "char8_t", "char16_t",
"char32_t", "class", "compl", "concept", "consteval", "constexpr", "constinit", "const_cast", "co_await",

View File

@ -53,7 +53,7 @@ Token::~Token()
delete mImpl;
}
static const std::set<std::string> controlFlowKeywords = {
static const std::unordered_set<std::string> controlFlowKeywords = {
"goto",
"do",
"if",
@ -127,7 +127,7 @@ void Token::update_property_info()
update_property_isStandardType();
}
static const std::set<std::string> stdTypes = { "bool"
static const std::unordered_set<std::string> stdTypes = { "bool"
, "_Bool"
, "char"
, "double"

View File

@ -3369,15 +3369,15 @@ void Tokenizer::setVarId()
// Variable declarations can't start with "return" etc.
#define NOTSTART_C "NOT", "case", "default", "goto", "not", "return", "sizeof", "typedef"
static const std::set<std::string> notstart_c = { NOTSTART_C };
static const std::set<std::string> notstart_cpp = { NOTSTART_C,
static const std::unordered_set<std::string> notstart_c = { NOTSTART_C };
static const std::unordered_set<std::string> notstart_cpp = { NOTSTART_C,
"delete", "friend", "new", "throw", "using", "virtual", "explicit", "const_cast", "dynamic_cast", "reinterpret_cast", "static_cast", "template"
};
void Tokenizer::setVarIdPass1()
{
// Variable declarations can't start with "return" etc.
const std::set<std::string>& notstart = (isC()) ? notstart_c : notstart_cpp;
const std::unordered_set<std::string>& notstart = (isC()) ? notstart_c : notstart_cpp;
VariableMap variableMap;
std::map<int, std::map<std::string, int> > structMembers;
@ -9676,7 +9676,7 @@ void Tokenizer::findGarbageCode() const
{
const bool isCPP11 = isCPP() && mSettings->standards.cpp >= Standards::CPP11;
const std::set<std::string> nonConsecutiveKeywords{ "break",
static const std::unordered_set<std::string> nonConsecutiveKeywords{ "break",
"continue",
"for",
"goto",
@ -9757,7 +9757,7 @@ void Tokenizer::findGarbageCode() const
}
// Keywords in global scope
std::set<std::string> nonGlobalKeywords{"break",
static const std::unordered_set<std::string> nonGlobalKeywords{"break",
"continue",
"for",
"goto",
@ -10528,7 +10528,7 @@ void Tokenizer::simplifyCPPAttribute()
}
}
static const std::set<std::string> keywords = {
static const std::unordered_set<std::string> keywords = {
"inline"
, "_inline"
, "__inline"

View File

@ -25,6 +25,7 @@
#include "token.h"
#include <string>
#include <unordered_set>
#include <vector>
class Settings;
@ -211,7 +212,7 @@ private:
/** settings */
const Settings* mSettings;
std::set<std::string> mKeywords;
std::unordered_set<std::string> mKeywords;
/** File is known to be C/C++ code */
bool mIsC;