From 7775934492bbfe6d392cda9a9eb803aa99c0928b Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Sun, 28 Aug 2011 13:32:42 -0400 Subject: [PATCH] really fix multi-dimensional arrays with undefined size --- lib/symboldatabase.cpp | 23 ++++++++++++++++------- lib/symboldatabase.h | 2 ++ test/testsymboldatabase.cpp | 11 +++++++++++ 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 03a398fb5..e6a80b9f2 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -813,7 +813,8 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti for (size_t j = 0; j < _variableList[i]->dimensions().size(); j++) { // check for a single token dimension that is a variable - if ((_variableList[i]->dimensions()[j].start == _variableList[i]->dimensions()[j].end) && + if (_variableList[i]->dimensions()[j].start && + (_variableList[i]->dimensions()[j].start == _variableList[i]->dimensions()[j].end) && _variableList[i]->dimensions()[j].start->varId()) { Dimension &dimension = const_cast(_variableList[i]->dimensions()[j]); @@ -1261,7 +1262,7 @@ const Token *SymbolDatabase::initBaseInfo(Scope *scope, const Token *tok) } base.name += tok2->str(); - base.scope = 0; + base.scope = NULL; // add unhandled templates if (tok2->next() && tok2->next()->str() == "<") @@ -1327,11 +1328,14 @@ bool SymbolDatabase::arrayDimensions(std::vector &dimensions, const T while (dim && dim->next() && dim->str() == "[") { Dimension dimension; - dimension.num = 0; - dimension.start = dim->next(); - dimension.end = dim->link()->previous(); - if (dimension.start == dimension.end && dimension.start->isNumber()) - dimension.num = MathLib::toLongNumber(dimension.start->str()); + // check for empty array dimension [] + if (dim->next()->str() != "]") + { + dimension.start = dim->next(); + dimension.end = dim->link()->previous(); + if (dimension.start == dimension.end && dimension.start->isNumber()) + dimension.num = MathLib::toLongNumber(dimension.start->str()); + } dimensions.push_back(dimension); dim = dim->link()->next(); isArray = true; @@ -1388,6 +1392,11 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Function else if (tok->str() == "[") { isArrayVar = symbolDatabase->arrayDimensions(dimensions, tok); + + // skip array dimension(s) + tok = tok->link(); + while (tok->next()->str() == "[") + tok = tok->next()->link(); } else if (tok->str() == "<") { diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 34ca43a87..5e8530850 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -46,6 +46,8 @@ enum AccessControl { Public, Protected, Private, Global, Namespace, Argument, Lo */ struct Dimension { + Dimension() : start(NULL), end(NULL), num(0) { } + const Token *start; // size start token const Token *end; // size end token MathLib::bigint num; // dimension length when size is a number, 0 if not known diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index c32a7c0de..d3904df16 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -102,6 +102,7 @@ private: TEST_CASE(hasGlobalVariables3); TEST_CASE(functionArgs1); + TEST_CASE(functionArgs2); TEST_CASE(symboldatabase1); TEST_CASE(symboldatabase2); @@ -658,6 +659,16 @@ private: ASSERT_EQUALS("", errout.str()); } + void functionArgs2() + { + GET_SYMBOL_DB("void f(int a[][4]) { }"); + const Variable *a = db->getVariableFromVarId(1); + ASSERT_EQUALS("a", a->nameToken()->str()); + ASSERT_EQUALS(2UL, a->dimensions().size()); + ASSERT_EQUALS(0UL, a->dimension(0)); + ASSERT_EQUALS(4UL, a->dimension(1)); + } + void symboldatabase1() { check("namespace foo {\n"