diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 69778794a..84081bc4c 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -4963,6 +4963,14 @@ void SymbolDatabase::setValueType(Token *tok, const ValueType &valuetype) } } + if (vt1 && vt1->containerTypeToken && parent->str() == "[") { + ValueType vtParent; + if (parsedecl(vt1->containerTypeToken, &vtParent, defaultSignedness, _settings)) { + setValueType(parent, vtParent); + return; + } + } + if (!vt1) return; if (parent->astOperand2() && !vt2) @@ -5090,8 +5098,15 @@ static const Token * parsedecl(const Token *type, ValueType * const valuetype, V valuetype->type = ValueType::Type::CONTAINER; valuetype->container = container; while (Token::Match(type, "%name%|::|<")) { - if (type->str() == "<" && type->link()) + if (type->str() == "<" && type->link()) { + if (container->type_templateArgNo >= 0) { + const Token *templateType = type->next(); + for (int j = 0; templateType && j < container->type_templateArgNo; j++) + templateType = templateType->nextTemplateArgument(); + valuetype->containerTypeToken = templateType; + } type = type->link(); + } type = type->next(); } continue; diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index ee06bc6f7..06b61adbe 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -1059,13 +1059,14 @@ public: unsigned int constness; // bit 0=data, bit 1=*, bit 2=** const Scope *typeScope; const Library::Container *container; + const Token *containerTypeToken; std::string originalTypeName; - ValueType() : sign(UNKNOWN_SIGN), type(UNKNOWN_TYPE), pointer(0U), constness(0U), typeScope(nullptr), container(nullptr) {} - ValueType(const ValueType &vt) : sign(vt.sign), type(vt.type), pointer(vt.pointer), constness(vt.constness), typeScope(vt.typeScope), container(vt.container), originalTypeName(vt.originalTypeName) {} - ValueType(enum Sign s, enum Type t, unsigned int p) : sign(s), type(t), pointer(p), constness(0U), typeScope(nullptr), container(nullptr) {} - ValueType(enum Sign s, enum Type t, unsigned int p, unsigned int c) : sign(s), type(t), pointer(p), constness(c), typeScope(nullptr), container(nullptr) {} - ValueType(enum Sign s, enum Type t, unsigned int p, unsigned int c, const std::string &otn) : sign(s), type(t), pointer(p), constness(c), typeScope(nullptr), container(nullptr), originalTypeName(otn) {} + ValueType() : sign(UNKNOWN_SIGN), type(UNKNOWN_TYPE), pointer(0U), constness(0U), typeScope(nullptr), container(nullptr), containerTypeToken(nullptr) {} + ValueType(const ValueType &vt) : sign(vt.sign), type(vt.type), pointer(vt.pointer), constness(vt.constness), typeScope(vt.typeScope), container(vt.container), containerTypeToken(vt.containerTypeToken), originalTypeName(vt.originalTypeName) {} + ValueType(enum Sign s, enum Type t, unsigned int p) : sign(s), type(t), pointer(p), constness(0U), typeScope(nullptr), container(nullptr), containerTypeToken(nullptr) {} + ValueType(enum Sign s, enum Type t, unsigned int p, unsigned int c) : sign(s), type(t), pointer(p), constness(c), typeScope(nullptr), container(nullptr), containerTypeToken(nullptr) {} + ValueType(enum Sign s, enum Type t, unsigned int p, unsigned int c, const std::string &otn) : sign(s), type(t), pointer(p), constness(c), typeScope(nullptr), container(nullptr), containerTypeToken(nullptr), originalTypeName(otn) {} static ValueType parseDecl(const Token *type, const Settings *settings); diff --git a/test/testio.cpp b/test/testio.cpp index e71134b54..b24fdc478 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -2851,8 +2851,8 @@ private: "void foo() {\n" " printf(\"%d %u %f\", v[0], v[0], v[0]);\n" "}\n"); - ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'int'.\n" - "[test.cpp:3]: (warning) %f in format string (no. 3) requires 'double' but the argument type is 'int'.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'signed int'.\n" + "[test.cpp:3]: (warning) %f in format string (no. 3) requires 'double' but the argument type is 'signed int'.\n", errout.str()); // #4999 (crash) check("int bar(int a);\n" diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index e38e81be8..b1cc449c6 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -4734,6 +4734,16 @@ private: ASSERT_EQUALS("container(C) *", typeOf("C*c=new C;","new","test.cpp",&sC)); ASSERT_EQUALS("container(C) *", typeOf("x=(C*)c;","(","test.cpp",&sC)); } + { + // Container (vector) + Settings set; + Library::Container vector; + vector.startPattern = "Vector"; + vector.type_templateArgNo = 0; + vector.arrayLike_indexOp = true; + set.library.containers["Vector"] = vector; + ASSERT_EQUALS("signed int", typeOf("Vector v; v[0]=3;", "[", "test.cpp", &set)); + } // new ASSERT_EQUALS("C *", typeOf("class C {}; x = new C();", "new"));