SymbolDatabase: Do not set wrong type for std::map etc items in range for loop
This commit is contained in:
parent
54b54567cf
commit
77434d093e
|
@ -453,6 +453,14 @@
|
|||
</optional>
|
||||
<empty/>
|
||||
</element>
|
||||
<element name="rangeItemRecordType">
|
||||
<oneOrMore>
|
||||
<element name="member">
|
||||
<attribute name="name"><ref name="DATA-NAME"/></attribute>
|
||||
<attribute name="templateParameter"><data type="integer"/></attribute>
|
||||
</element>
|
||||
</oneOrMore>
|
||||
</element>
|
||||
<element name="size">
|
||||
<optional>
|
||||
<attribute name="templateParameter"><data type="integer"/></attribute>
|
||||
|
|
|
@ -8230,6 +8230,10 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init
|
|||
</container>
|
||||
<container id="stdMultiMap" startPattern="std :: multimap|unordered_multimap <" inherits="stdContainer">
|
||||
<type templateParameter="1" associative="std-like"/>
|
||||
<rangeItemRecordType>
|
||||
<member name="first" templateParameter="0"/>
|
||||
<member name="second" templateParameter="1"/>
|
||||
</rangeItemRecordType>
|
||||
<access>
|
||||
<function name="at" yields="at_index"/>
|
||||
<function name="count" action="find"/>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -246,9 +246,14 @@ public:
|
|||
Action action;
|
||||
Yield yield;
|
||||
};
|
||||
struct RangeItemRecordTypeItem {
|
||||
std::string name;
|
||||
int templateParameter;
|
||||
};
|
||||
std::string startPattern, startPattern2, endPattern, itEndPattern;
|
||||
std::map<std::string, Function> functions;
|
||||
int type_templateArgNo;
|
||||
std::vector<RangeItemRecordTypeItem> rangeItemRecordType;
|
||||
int size_templateArgNo;
|
||||
bool arrayLike_indexOp;
|
||||
bool stdStringLike;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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<std::string, bool> 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"
|
||||
|
|
Loading…
Reference in New Issue