11/*
22 * Cppcheck - A tool for static C/C++ code analysis
3- * Copyright (C) 2007-2026 Cppcheck team.
3+ * Copyright (C) 2007-2025 Cppcheck team.
44 *
55 * This program is free software: you can redistribute it and/or modify
66 * it under the terms of the GNU General Public License as published by
@@ -1043,7 +1043,7 @@ void Tokenizer::simplifyTypedef()
10431043 if (t != ts.nameToken ())
10441044 existing_data_type += t->str () + " " ;
10451045 }
1046- numberOfTypedefs[ts.name ()].emplace ( std::move ( existing_data_type) );
1046+ numberOfTypedefs[ts.name ()].insert ( existing_data_type);
10471047 continue ;
10481048 }
10491049 }
@@ -3788,7 +3788,7 @@ void Tokenizer::simplifyParenthesizedLibraryFunctions()
37883788 if (!Token::simpleMatch (tok, " ) (" ))
37893789 continue ;
37903790 Token *rpar = tok, *lpar = tok->link ();
3791- if (!lpar || (Token::Match (lpar->previous (), " %name%" ) && !Token::Match ( lpar->previous (), " return|delete|throw " )))
3791+ if (!lpar || (Token::Match (lpar->previous (), " %name%" ) && !lpar->previous ()-> isKeyword ( )))
37923792 continue ;
37933793 const Token *ftok = rpar->previous ();
37943794 if (mSettings .library .isNotLibraryFunction (ftok))
@@ -4231,10 +4231,13 @@ void Tokenizer::simplifyTemplates()
42314231namespace {
42324232 /* * Class used in Tokenizer::setVarIdPass1 */
42334233 class VariableMap {
4234+ public:
4235+ struct VarInfo { nonneg int id{}; bool assigned{}; };
4236+ using MapType = std::unordered_map<std::string, VarInfo>;
42344237 private:
4235- std::unordered_map<std::string, nonneg int > mVariableId ;
4236- std::unordered_map<std::string, nonneg int > mVariableId_global ;
4237- std::stack<std::vector<std::pair<std::string, nonneg int > >> mScopeInfo ;
4238+ MapType mVariableId ;
4239+ MapType mVariableId_global ;
4240+ std::stack<std::vector<MapType::value_type >> mScopeInfo ;
42384241 mutable nonneg int mVarId {};
42394242 public:
42404243 VariableMap () = default ;
@@ -4245,7 +4248,10 @@ namespace {
42454248 return mVariableId .find (varname) != mVariableId .end ();
42464249 }
42474250
4248- const std::unordered_map<std::string, nonneg int >& map (bool global) const {
4251+ const MapType& map (bool global) const {
4252+ return global ? mVariableId_global : mVariableId ;
4253+ }
4254+ MapType& map (bool global) {
42494255 return global ? mVariableId_global : mVariableId ;
42504256 }
42514257 nonneg int & getVarId () {
@@ -4265,8 +4271,8 @@ bool VariableMap::leaveScope()
42654271 if (mScopeInfo .empty ())
42664272 return false ;
42674273
4268- for (const std::pair<std::string, nonneg int > & outerVariable : mScopeInfo .top ()) {
4269- if (outerVariable.second != 0 )
4274+ for (const MapType::value_type & outerVariable : mScopeInfo .top ()) {
4275+ if (outerVariable.second . id != 0 )
42704276 mVariableId [outerVariable.first ] = outerVariable.second ;
42714277 else
42724278 mVariableId .erase (outerVariable.first );
@@ -4278,21 +4284,22 @@ bool VariableMap::leaveScope()
42784284void VariableMap::addVariable (const std::string& varname, bool globalNamespace)
42794285{
42804286 if (mScopeInfo .empty ()) {
4281- mVariableId [varname] = ++mVarId ;
4287+ mVariableId [varname]. id = ++mVarId ;
42824288 if (globalNamespace)
42834289 mVariableId_global [varname] = mVariableId [varname];
42844290 return ;
42854291 }
42864292 const auto it = mVariableId .find (varname);
42874293 if (it == mVariableId .end ()) {
4288- mScopeInfo .top ().emplace_back (varname, 0 );
4289- mVariableId [varname] = ++mVarId ;
4294+ mScopeInfo .top ().emplace_back (varname, VarInfo{} );
4295+ mVariableId [varname]. id = ++mVarId ;
42904296 if (globalNamespace)
42914297 mVariableId_global [varname] = mVariableId [varname];
42924298 return ;
42934299 }
42944300 mScopeInfo .top ().emplace_back (varname, it->second );
4295- it->second = ++mVarId ;
4301+ it->second .id = ++mVarId ;
4302+ it->second .assigned = false ;
42964303}
42974304
42984305/* *
@@ -4509,14 +4516,14 @@ static void setVarIdStructMembers(Token *&tok1,
45094516
45104517static void addTemplateVarIdUsage (const std::string &tokstr,
45114518 const std::map<std::string, std::set<std::string>>& templateVarUsage,
4512- const std::unordered_map<std::string, nonneg int > & variableMap,
4519+ const VariableMap::MapType & variableMap,
45134520 std::set<nonneg int >& templateVarIdUsage) {
45144521 const auto v = templateVarUsage.find (tokstr);
45154522 if (v != templateVarUsage.end ()) {
45164523 for (const std::string& varname: v->second ) {
45174524 const auto it = variableMap.find (varname);
45184525 if (it != variableMap.end ())
4519- templateVarIdUsage.insert (it->second );
4526+ templateVarIdUsage.insert (it->second . id );
45204527 }
45214528 }
45224529}
@@ -4573,7 +4580,7 @@ static bool setVarIdClassDeclaration(Token* const startToken,
45734580 } else if (initList && indentlevel == 0 && Token::Match (tok->previous (), " [,:] %name% [({]" )) {
45744581 const auto it = variableMap.map (false ).find (tok->str ());
45754582 if (it != variableMap.map (false ).end ()) {
4576- tok->varId (it->second );
4583+ tok->varId (it->second . id );
45774584 }
45784585 } else if (tok->isName () && tok->varId () <= scopeStartVarId) {
45794586 if (indentlevel > 0 || initList) {
@@ -4591,7 +4598,7 @@ static bool setVarIdClassDeclaration(Token* const startToken,
45914598 if (!inEnum) {
45924599 const auto it = variableMap.map (false ).find (tok->str ());
45934600 if (it != variableMap.map (false ).end ()) {
4594- tok->varId (it->second );
4601+ tok->varId (it->second . id );
45954602 setVarIdStructMembers (tok, structMembers, variableMap.getVarId ());
45964603 } else if (tok->str ().back () == ' >' ) {
45974604 addTemplateVarIdUsage (tok->str (), templateVarUsage, variableMap.map (false ), templateVarIdUsage);
@@ -4887,7 +4894,7 @@ void Tokenizer::setVarIdPass1()
48874894 if (declTypeTok) {
48884895 for (Token *declTok = declTypeTok->linkAt (1 ); declTok != declTypeTok; declTok = declTok->previous ()) {
48894896 if (declTok->isName () && !Token::Match (declTok->previous (), " ::|." ) && variableMap.hasVariable (declTok->str ()))
4890- declTok->varId (variableMap.map (false ).find (declTok->str ())->second );
4897+ declTok->varId (variableMap.map (false ).find (declTok->str ())->second . id );
48914898 }
48924899 }
48934900
@@ -4967,7 +4974,7 @@ void Tokenizer::setVarIdPass1()
49674974 Token::Match (tok->tokAt (-1 ), " :: %name%" ))) {
49684975 const auto it = variableMap.map (false ).find (tok->str ());
49694976 if (it != variableMap.map (false ).end ())
4970- tok->varId (it->second );
4977+ tok->varId (it->second . id );
49714978 }
49724979 tok = tok->next ();
49734980 }
@@ -5042,8 +5049,11 @@ void Tokenizer::setVarIdPass1()
50425049 !Token::simpleMatch (tok->next (), " : ;" ) && !(tok->tokAt (-1 ) && Token::Match (tok->tokAt (-2 ), " {|, ." ))) {
50435050 const auto it = variableMap.map (globalNamespace).find (tok->str ());
50445051 if (it != variableMap.map (globalNamespace).end ()) {
5045- tok->varId (it->second );
5046- setVarIdStructMembers (tok, structMembers, variableMap.getVarId ());
5052+ if (!it->second .assigned || !Token::Match (tok->previous (), " %type% %name% (" ) || tok->previous ()->isKeyword ()) {
5053+ it->second .assigned = true ;
5054+ tok->varId (it->second .id );
5055+ setVarIdStructMembers (tok, structMembers, variableMap.getVarId ());
5056+ }
50475057 }
50485058 }
50495059 } else if (Token::Match (tok, " ::|. %name%" ) && Token::Match (tok->previous (), " )|]|>|%name%" )) {
0 commit comments