diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 474f6ef45bb..68500acdfa3 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -7201,6 +7201,8 @@ static const Token* parsedecl(const Token* type, if (!type->originalName().empty()) valuetype->originalTypeName = type->originalName(); type = type->next(); + if (type && type->link() && type->str() == "<") + type = type->link()->next(); } // Set signedness for integral types.. diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 0bd82aacc5a..3dbd434c521 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -225,6 +225,7 @@ class TestSymbolDatabase : public TestFixture { TEST_CASE(VariableValueType4); // smart pointer type TEST_CASE(VariableValueType5); // smart pointer type TEST_CASE(VariableValueTypeReferences); + TEST_CASE(VariableValueTypeTemplate); TEST_CASE(findVariableType1); TEST_CASE(findVariableType2); @@ -1370,6 +1371,26 @@ class TestSymbolDatabase : public TestFixture { } } + void VariableValueTypeTemplate() { + { + GET_SYMBOL_DB("template \n" // #12393 + "struct S {\n" + " struct U {\n" + " S* p;\n" + " };\n" + " U u;\n" + "};\n"); + const Variable* const p = db->getVariableFromVarId(1); + ASSERT_EQUALS(p->name(), "p"); + ASSERT(p->valueType()); + ASSERT(p->valueType()->pointer == 1); + ASSERT(p->valueType()->constness == 0); + ASSERT(p->valueType()->reference == Reference::None); + ASSERT_EQUALS(p->scope()->className, "U"); + ASSERT_EQUALS(p->typeScope()->className, "S"); + } + } + void findVariableType1() { GET_SYMBOL_DB("class A {\n" "public:\n" diff --git a/test/testtype.cpp b/test/testtype.cpp index aa5f1f2efef..882754b6547 100644 --- a/test/testtype.cpp +++ b/test/testtype.cpp @@ -403,6 +403,16 @@ class TestType : public TestFixture { " long long j = *(p++);\n" "}\n", settings); ASSERT_EQUALS("", errout.str()); + + check("template \n" // #12393 + "struct S {\n" + " S& operator=(const S&) { return *this; }\n" + " struct U {\n" + " S* p;\n" + " };\n" + " U u;\n" + "};\n", settings); + ASSERT_EQUALS("", errout.str()); // don't crash } void longCastReturn() {