From 05a3e6807b3d9b20e39fcd1e56d8c0b0123338ed Mon Sep 17 00:00:00 2001 From: IOBYTE Date: Thu, 31 Jan 2019 10:53:51 -0500 Subject: [PATCH] Fixed #8950 and #8952 (improve type alias support) (#1633) * Fixed #8950 and #8952 (improve type alias support) * fix travis build --- lib/symboldatabase.cpp | 15 ++++++++---- test/testsymboldatabase.cpp | 48 +++++++++++++++++++++++++++++++++++++ test/testtokenize.cpp | 25 +++++++++++++++++++ 3 files changed, 84 insertions(+), 4 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 53aee0707..606d84e90 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -863,8 +863,10 @@ void SymbolDatabase::createSymbolDatabaseNeedInitialization() // does this type need initialization? if (var->type()->needInitialization == Type::True) needInitialization = true; - else if (var->type()->needInitialization == Type::Unknown) - unknown = true; + else if (var->type()->needInitialization == Type::Unknown) { + if (!(var->valueType() && var->valueType()->type == ValueType::CONTAINER)) + unknown = true; + } } } else if (!var->hasDefault()) needInitialization = true; @@ -4482,8 +4484,13 @@ const Scope *Scope::findRecordInNestedList(const std::string & name) const const Type * nested_type = findType(name); - if (nested_type) - return nested_type->classScope; + if (nested_type) { + if (nested_type->isTypeAlias()) { + if (nested_type->typeStart == nested_type->typeEnd) + return findRecordInNestedList(nested_type->typeStart->str()); + } else + return nested_type->classScope; + } return nullptr; } diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 9fd770dc9..78f2d4706 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -386,6 +386,8 @@ private: TEST_CASE(using1); TEST_CASE(using2); // #8331 (segmentation fault) TEST_CASE(using3); // #8343 (segmentation fault) + TEST_CASE(using4); // #8952 (unknown type) + TEST_CASE(using5); // #8950 (couldn't resolve all user defined types) } void array() { @@ -6890,6 +6892,52 @@ private: ASSERT(db != nullptr); ASSERT_EQUALS("", errout.str()); } + + void using4() { // #8952 (unknown type) + const Standards::cppstd_t original_std = settings1.standards.cpp; + settings1.standards.cpp = Standards::CPP11; + settings1.debugwarnings = true; + GET_SYMBOL_DB("class A {\n" + "public:\n" + " enum Type { Null };\n" + "};\n" + "using V = A;\n" + "V::Type value;"); + settings1.standards.cpp = original_std; + settings1.debugwarnings = false; + + vartok = Token::findsimplematch(tokenizer.tokens(), "value"); + ASSERT(db && vartok && vartok->valueType()); + if (db && vartok && vartok->valueType()) { + ASSERT_EQUALS(0, vartok->valueType()->constness); + ASSERT_EQUALS(0, vartok->valueType()->pointer); + ASSERT_EQUALS(ValueType::SIGNED, vartok->valueType()->sign); + ASSERT_EQUALS(ValueType::INT, vartok->valueType()->type); + const Variable *var = vartok->variable(); + ASSERT(var && var->type() && var->type()->isEnumType()); + } + } + + void using5() { // #8950 (couldn't resolve all user defined types) + const Standards::cppstd_t original_std = settings1.standards.cpp; + settings1.standards.cpp = Standards::CPP11; + settings1.debugwarnings = true; + GET_SYMBOL_DB("class A {\n" + "public:\n" + " using MapType = std::map;\n" + "private:\n" + " MapType m;\n" + "};"); + settings1.standards.cpp = original_std; + settings1.debugwarnings = false; + + ASSERT_EQUALS("", errout.str()); + ASSERT(db && db->scopeList.size() == 2); // global + class + if (db && db->scopeList.size() == 2) { + const Scope *scope = &db->scopeList.back(); + ASSERT(scope->type == Scope::eClass && scope->definedType && scope->definedType->needInitialization == Type::False); + } + } }; REGISTER_TEST(TestSymbolDatabase) diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index a1b3eb5ab..a49d74f52 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -483,6 +483,8 @@ private: // --check-config TEST_CASE(checkConfiguration); + + TEST_CASE(unknownType); // #8952 } std::string tokenizeAndStringify(const char code[], bool simplify = false, bool expand = true, Settings::PlatformType platform = Settings::Native, const char* filename = "test.cpp", bool cpp11 = true) { @@ -8760,6 +8762,29 @@ private: checkConfig("void f() { DEBUG(x();y()); }"); ASSERT_EQUALS("[test.cpp:1]: (information) Ensure that 'DEBUG' is defined either using -I, --include or -D.\n", errout.str()); } + + void unknownType() { // #8952 + // Clear the error log + errout.str(""); + Settings settings; + settings.debugwarnings = true; + + char code[] = "class A {\n" + "public:\n" + " enum Type { Null };\n" + "};\n" + "using V = A;\n" + "V::Type value;"; + + // Tokenize.. + Tokenizer tokenizer(&settings, this); + std::istringstream istr(code); + tokenizer.tokenize(istr, "test.cpp"); + + tokenizer.printUnknownTypes(); + + ASSERT_EQUALS("", errout.str()); + } }; REGISTER_TEST(TestTokenizer)