Merge pull request #661 from simartin/ticket_6957

Ticket #6957: Properly handle arrays of pointers in CheckClass::constructors
This commit is contained in:
orbitcowboy 2015-08-29 00:03:18 +02:00
commit f8083e9fba
5 changed files with 41 additions and 1 deletions

View File

@ -148,7 +148,7 @@ void CheckClass::constructors()
continue;
// Check if this is a class constructor
if (!var->isPointer() && var->isClass() && func->type == Function::eConstructor) {
if (!var->isPointer() && !var->isPointerArray() && var->isClass() && func->type == Function::eConstructor) {
// Unknown type so assume it is initialized
if (!var->type())
continue;

View File

@ -1422,6 +1422,10 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const
return false;
}
bool Variable::isPointerArray() const {
return isArray() && nameToken() && nameToken()->previous() && (nameToken()->previous()->str() == "*");
}
const Token * Variable::declEndToken() const
{
Token const * declEnd = typeStartToken();

View File

@ -393,6 +393,12 @@ public:
return isPointer() && getFlag(fIsArray);
}
/**
* Is variable an array of pointers
* @return true if array or pointers, false otherwise
*/
bool isPointerArray() const;
/**
* Is array or pointer variable.
* @return true if pointer or array, false otherwise

View File

@ -148,6 +148,7 @@ private:
TEST_CASE(uninitVarArray6);
TEST_CASE(uninitVarArray7);
TEST_CASE(uninitVarArray8);
TEST_CASE(uninitVarArray9); // ticket #6957
TEST_CASE(uninitVarArray2D);
TEST_CASE(uninitVarArray3D);
TEST_CASE(uninitVarCpp11Init1);
@ -2404,6 +2405,17 @@ private:
ASSERT_EQUALS("", errout.str());
}
void uninitVarArray9() { // #6957
check("class BaseGDL;\n"
"struct IxExprListT {\n"
"private:\n"
" BaseGDL* eArr[3];\n"
"public:\n"
" IxExprListT() {}\n"
"};");
ASSERT_EQUALS("[test.cpp:6]: (warning) Member variable 'IxExprListT::eArr' is not initialized in the constructor.\n", errout.str());
}
void uninitVarArray2D() {
check("class John\n"
"{\n"

View File

@ -113,6 +113,7 @@ private:
TEST_CASE(test_isVariableDeclarationIdentifiesDeclarationWithIndirection);
TEST_CASE(test_isVariableDeclarationIdentifiesDeclarationWithMultipleIndirection);
TEST_CASE(test_isVariableDeclarationIdentifiesArray);
TEST_CASE(test_isVariableDeclarationIdentifiesPointerArray);
TEST_CASE(test_isVariableDeclarationIdentifiesOfArrayPointers);
TEST_CASE(isVariableDeclarationIdentifiesTemplatedPointerVariable);
TEST_CASE(isVariableDeclarationIdentifiesTemplatedPointerToPointerVariable);
@ -491,6 +492,22 @@ private:
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(true == v.isArray());
ASSERT(false == v.isPointer());
ASSERT(false == v.isPointerArray());
ASSERT(false == v.isReference());
}
void test_isVariableDeclarationIdentifiesPointerArray() {
reset();
givenACodeSampleToTokenize arr("A *a[5];");
bool result = si.isVariableDeclaration(arr.tokens(), vartok, typetok);
ASSERT_EQUALS(true, result);
ASSERT_EQUALS("a", vartok->str());
ASSERT_EQUALS("A", typetok->str());
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings.library);
ASSERT(false == v.isPointer());
ASSERT(true == v.isArray());
ASSERT(false == v.isPointerToArray());
ASSERT(true == v.isPointerArray());
ASSERT(false == v.isReference());
}
@ -505,6 +522,7 @@ private:
ASSERT(true == v.isPointer());
ASSERT(false == v.isArray());
ASSERT(true == v.isPointerToArray());
ASSERT(false == v.isPointerArray());
ASSERT(false == v.isReference());
}