isVariableDeclaration: Handle pointer to const pointer (#1395)
isVariableDeclaration did not handle pointer to const pointer, or pointer to volatile pointer. This resulted in FPs in examples like the following: class Fred { public: const char *const *data; const char *const *getData() { return data; }; } where cppcheck would say getData could be static, since it didn't recognize const char *const *data as a variable declaration.
This commit is contained in:
parent
ca5542131a
commit
5e120b567c
|
@ -3550,6 +3550,17 @@ static const Token* skipPointers(const Token* tok)
|
||||||
return tok;
|
return tok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const Token* skipPointersAndQualifiers(const Token* tok)
|
||||||
|
{
|
||||||
|
tok = skipPointers(tok);
|
||||||
|
while (Token::Match(tok, "const|volatile")) {
|
||||||
|
tok = tok->next();
|
||||||
|
tok = skipPointers(tok);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tok;
|
||||||
|
}
|
||||||
|
|
||||||
bool Scope::isVariableDeclaration(const Token* const tok, const Token*& vartok, const Token*& typetok) const
|
bool Scope::isVariableDeclaration(const Token* const tok, const Token*& vartok, const Token*& typetok) const
|
||||||
{
|
{
|
||||||
const bool isCPP = check && check->mTokenizer->isCPP();
|
const bool isCPP = check && check->mTokenizer->isCPP();
|
||||||
|
@ -3582,7 +3593,7 @@ bool Scope::isVariableDeclaration(const Token* const tok, const Token*& vartok,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (Token::Match(localTypeTok, "%type%")) {
|
} else if (Token::Match(localTypeTok, "%type%")) {
|
||||||
localVarTok = skipPointers(localTypeTok->strAt(1)=="const"?localTypeTok->tokAt(2):localTypeTok->next());
|
localVarTok = skipPointersAndQualifiers(localTypeTok->next());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!localVarTok)
|
if (!localVarTok)
|
||||||
|
|
|
@ -196,6 +196,7 @@ private:
|
||||||
TEST_CASE(constArrayOperator); // #4406
|
TEST_CASE(constArrayOperator); // #4406
|
||||||
TEST_CASE(constRangeBasedFor); // #5514
|
TEST_CASE(constRangeBasedFor); // #5514
|
||||||
TEST_CASE(const_shared_ptr);
|
TEST_CASE(const_shared_ptr);
|
||||||
|
TEST_CASE(constPtrToConstPtr);
|
||||||
|
|
||||||
TEST_CASE(initializerListOrder);
|
TEST_CASE(initializerListOrder);
|
||||||
TEST_CASE(initializerListUsage);
|
TEST_CASE(initializerListUsage);
|
||||||
|
@ -6215,6 +6216,14 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void constPtrToConstPtr() {
|
||||||
|
checkConst("class Fred {\n"
|
||||||
|
"public:\n"
|
||||||
|
" const char *const *data;\n"
|
||||||
|
" const char *const *getData() { return data; }\n}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:4]: (style, inconclusive) Technically the member function 'Fred::getData' can be const.\n", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void checkInitializerListOrder(const char code[]) {
|
void checkInitializerListOrder(const char code[]) {
|
||||||
// Clear the error log
|
// Clear the error log
|
||||||
errout.str("");
|
errout.str("");
|
||||||
|
|
|
@ -141,6 +141,10 @@ private:
|
||||||
TEST_CASE(isVariableDeclarationRValueRef);
|
TEST_CASE(isVariableDeclarationRValueRef);
|
||||||
TEST_CASE(isVariableDeclarationDoesNotIdentifyCase);
|
TEST_CASE(isVariableDeclarationDoesNotIdentifyCase);
|
||||||
TEST_CASE(isVariableStlType);
|
TEST_CASE(isVariableStlType);
|
||||||
|
TEST_CASE(isVariablePointerToConstPointer);
|
||||||
|
TEST_CASE(isVariablePointerToVolatilePointer);
|
||||||
|
TEST_CASE(isVariablePointerToConstVolatilePointer);
|
||||||
|
TEST_CASE(isVariableMultiplePointersAndQualifiers);
|
||||||
|
|
||||||
TEST_CASE(VariableValueType1);
|
TEST_CASE(VariableValueType1);
|
||||||
TEST_CASE(VariableValueType2);
|
TEST_CASE(VariableValueType2);
|
||||||
|
@ -954,6 +958,50 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void isVariablePointerToConstPointer() {
|
||||||
|
reset();
|
||||||
|
givenACodeSampleToTokenize var("char* const * s;");
|
||||||
|
bool result = nullScope.isVariableDeclaration(var.tokens(), vartok, typetok);
|
||||||
|
ASSERT_EQUALS(true, result);
|
||||||
|
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings1);
|
||||||
|
ASSERT(false == v.isArray());
|
||||||
|
ASSERT(true == v.isPointer());
|
||||||
|
ASSERT(false == v.isReference());
|
||||||
|
}
|
||||||
|
|
||||||
|
void isVariablePointerToVolatilePointer() {
|
||||||
|
reset();
|
||||||
|
givenACodeSampleToTokenize var("char* volatile * s;");
|
||||||
|
bool result = nullScope.isVariableDeclaration(var.tokens(), vartok, typetok);
|
||||||
|
ASSERT_EQUALS(true, result);
|
||||||
|
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings1);
|
||||||
|
ASSERT(false == v.isArray());
|
||||||
|
ASSERT(true == v.isPointer());
|
||||||
|
ASSERT(false == v.isReference());
|
||||||
|
}
|
||||||
|
|
||||||
|
void isVariablePointerToConstVolatilePointer() {
|
||||||
|
reset();
|
||||||
|
givenACodeSampleToTokenize var("char* const volatile * s;");
|
||||||
|
bool result = nullScope.isVariableDeclaration(var.tokens(), vartok, typetok);
|
||||||
|
ASSERT_EQUALS(true, result);
|
||||||
|
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings1);
|
||||||
|
ASSERT(false == v.isArray());
|
||||||
|
ASSERT(true == v.isPointer());
|
||||||
|
ASSERT(false == v.isReference());
|
||||||
|
}
|
||||||
|
|
||||||
|
void isVariableMultiplePointersAndQualifiers() {
|
||||||
|
reset();
|
||||||
|
givenACodeSampleToTokenize var("const char* const volatile * const volatile * const volatile * const volatile s;");
|
||||||
|
bool result = nullScope.isVariableDeclaration(var.tokens()->next(), vartok, typetok);
|
||||||
|
ASSERT_EQUALS(true, result);
|
||||||
|
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0, &settings1);
|
||||||
|
ASSERT(false == v.isArray());
|
||||||
|
ASSERT(true == v.isPointer());
|
||||||
|
ASSERT(false == v.isReference());
|
||||||
|
}
|
||||||
|
|
||||||
void arrayMemberVar1() {
|
void arrayMemberVar1() {
|
||||||
GET_SYMBOL_DB("struct Foo {\n"
|
GET_SYMBOL_DB("struct Foo {\n"
|
||||||
" int x;\n"
|
" int x;\n"
|
||||||
|
|
Loading…
Reference in New Issue