From 77434d093e5d76357597d355fa14089c13b8d542 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 11 Dec 2021 15:16:54 +0100 Subject: [PATCH] SymbolDatabase: Do not set wrong type for std::map etc items in range for loop --- cfg/cppcheck-cfg.rng | 8 ++++++++ cfg/std.cfg | 4 ++++ lib/library.cpp | 9 +++++++++ lib/library.h | 5 +++++ lib/symboldatabase.cpp | 6 ++++-- test/testsymboldatabase.cpp | 11 +++++++++++ 6 files changed, 41 insertions(+), 2 deletions(-) diff --git a/cfg/cppcheck-cfg.rng b/cfg/cppcheck-cfg.rng index 8a4d04f77..392159e13 100644 --- a/cfg/cppcheck-cfg.rng +++ b/cfg/cppcheck-cfg.rng @@ -453,6 +453,14 @@ + + + + + + + + diff --git a/cfg/std.cfg b/cfg/std.cfg index 3181ea4b9..530abcad6 100644 --- a/cfg/std.cfg +++ b/cfg/std.cfg @@ -8230,6 +8230,10 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init + + + + diff --git a/lib/library.cpp b/lib/library.cpp index efbcad8d8..806941853 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -506,6 +506,15 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) if (unstableType.find("insert") != std::string::npos) container.unstableInsert = true; } + } else if (containerNodeName == "rangeItemRecordType") { + for (const tinyxml2::XMLElement* memberNode = node->FirstChildElement(); memberNode; memberNode = memberNode->NextSiblingElement()) { + const char *memberName = memberNode->Attribute("name"); + const char *memberTemplateParameter = memberNode->Attribute("templateParameter"); + struct Container::RangeItemRecordTypeItem member; + member.name = memberName ? memberName : ""; + member.templateParameter = memberTemplateParameter ? std::atoi(memberTemplateParameter) : -1; + container.rangeItemRecordType.emplace_back(member); + } } else unknown_elements.insert(containerNodeName); } diff --git a/lib/library.h b/lib/library.h index 1eddc8fdd..b1be6bb63 100644 --- a/lib/library.h +++ b/lib/library.h @@ -246,9 +246,14 @@ public: Action action; Yield yield; }; + struct RangeItemRecordTypeItem { + std::string name; + int templateParameter; + }; std::string startPattern, startPattern2, endPattern, itEndPattern; std::map functions; int type_templateArgNo; + std::vector rangeItemRecordType; int size_templateArgNo; bool arrayLike_indexOp; bool stdStringLike; diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 859892d18..47199e0e4 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -6008,7 +6008,10 @@ void SymbolDatabase::setValueType(Token *tok, const ValueType &valuetype) bool setType = false; ValueType autovt; const Type *templateArgType = nullptr; // container element type / smart pointer type - if (vt2->containerTypeToken) { + if (!vt2->container->rangeItemRecordType.empty()) { + setType = true; + autovt.type = ValueType::Type::RECORD; + } else if (vt2->containerTypeToken) { if (mSettings->library.isSmartPointer(vt2->containerTypeToken)) { const Token *smartPointerTypeTok = vt2->containerTypeToken; while (Token::Match(smartPointerTypeTok, "%name%|::")) @@ -6023,7 +6026,6 @@ void SymbolDatabase::setValueType(Token *tok, const ValueType &valuetype) setType = true; templateArgType = vt2->containerTypeToken->type(); } - } if (setType) { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 68074267e..15960b5f7 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -478,6 +478,7 @@ private: TEST_CASE(auto13); TEST_CASE(auto14); TEST_CASE(auto15); // C++17 auto deduction from braced-init-list + TEST_CASE(auto16); TEST_CASE(unionWithConstructor); @@ -8354,6 +8355,16 @@ private: ASSERT_EQUALS(ValueType::Type::DOUBLE, var2->valueType()->type); } + void auto16() { + GET_SYMBOL_DB("void foo(std::map x) {\n" + " for (const auto& i: x) {}\n" + "}\n"); + ASSERT_EQUALS(3, db->variableList().size()); + const Variable *i = db->variableList().back(); + ASSERT(i->valueType()); + ASSERT_EQUALS(ValueType::Type::RECORD, i->valueType()->type); + } + void unionWithConstructor() { GET_SYMBOL_DB("union Fred {\n" " Fred(int x) : i(x) { }\n"