Fix #9411 (new daca crash related to using namespace) (#2264)

This commit is contained in:
IOBYTE 2019-10-12 05:39:14 -04:00 committed by Daniel Marjamäki
parent e24008544e
commit f99e83ece0
3 changed files with 60 additions and 3 deletions

View File

@ -2030,8 +2030,23 @@ static bool usingNamespace(const Scope *scope, const Token *first, const Token *
if (offset) { if (offset) {
while (scope) { while (scope) {
for (const auto & info : scope->usingList) { for (const auto & info : scope->usingList) {
if (name == qualifiedName(info.scope)) if (info.scope) {
return true; if (name == qualifiedName(info.scope))
return true;
}
// no scope so get name from using
else {
const Token *start = info.start->tokAt(2);
std::string nsName;
while (start && start->str() != ";") {
if (!nsName.empty())
nsName += " ";
nsName += start->str();
start = start->next();
}
if (nsName == name)
return true;
}
} }
scope = scope->nestedIn; scope = scope->nestedIn;
} }

View File

@ -2877,7 +2877,7 @@ void Tokenizer::calculateScopes()
if (Token::Match(tok, "using namespace %name% ::|<|;")) { if (Token::Match(tok, "using namespace %name% ::|<|;")) {
std::string usingNamespaceName; std::string usingNamespaceName;
for (const Token* namespaceNameToken = tok->tokAt(2); for (const Token* namespaceNameToken = tok->tokAt(2);
!Token::simpleMatch(namespaceNameToken, ";"); namespaceNameToken && namespaceNameToken->str() != ";";
namespaceNameToken = namespaceNameToken->next()) { namespaceNameToken = namespaceNameToken->next()) {
usingNamespaceName += namespaceNameToken->str(); usingNamespaceName += namespaceNameToken->str();
usingNamespaceName += " "; usingNamespaceName += " ";

View File

@ -303,6 +303,7 @@ private:
TEST_CASE(symboldatabase78); // #9147 TEST_CASE(symboldatabase78); // #9147
TEST_CASE(symboldatabase79); // #9392 TEST_CASE(symboldatabase79); // #9392
TEST_CASE(symboldatabase80); // #9389 TEST_CASE(symboldatabase80); // #9389
TEST_CASE(symboldatabase81); // #9411
TEST_CASE(createSymbolDatabaseFindAllScopes1); TEST_CASE(createSymbolDatabaseFindAllScopes1);
@ -4349,6 +4350,47 @@ private:
} }
} }
void symboldatabase81() { // #9411
{
GET_SYMBOL_DB("namespace Terminal {\n"
" class Complete {\n"
" public:\n"
" std::string act(const Parser::Action *act);\n"
" };\n"
"}\n"
"using namespace std;\n"
"using namespace Parser;\n"
"using namespace Terminal;\n"
"string Complete::act(const Action *act) { }");
ASSERT(db->scopeList.size() == 4);
ASSERT(db->functionScopes.size() == 1);
const Scope *scope = db->findScopeByName("Complete");
ASSERT(scope);
ASSERT(scope->functionList.size() == 1);
ASSERT(scope->functionList.front().name() == "act");
ASSERT(scope->functionList.front().hasBody() == true);
}
{
GET_SYMBOL_DB("namespace Terminal {\n"
" class Complete {\n"
" public:\n"
" std::string act(const Foo::Parser::Action *act);\n"
" };\n"
"}\n"
"using namespace std;\n"
"using namespace Foo::Parser;\n"
"using namespace Terminal;\n"
"string Complete::act(const Action *act) { }");
ASSERT(db->scopeList.size() == 4);
ASSERT(db->functionScopes.size() == 1);
const Scope *scope = db->findScopeByName("Complete");
ASSERT(scope);
ASSERT(scope->functionList.size() == 1);
ASSERT(scope->functionList.front().name() == "act");
ASSERT(scope->functionList.front().hasBody() == true);
}
}
void createSymbolDatabaseFindAllScopes1() { void createSymbolDatabaseFindAllScopes1() {
GET_SYMBOL_DB("void f() { union {int x; char *p;} a={0}; }"); GET_SYMBOL_DB("void f() { union {int x; char *p;} a={0}; }");
ASSERT(db->scopeList.size() == 3); ASSERT(db->scopeList.size() == 3);