Refactorized type handling in CheckIO and CheckOther:
- Added several types (std::) to isComplexType - Types in namespace std:: are considered to have no side-effects (solved one TODO) - Scope of a pointer can be limited without side effects
This commit is contained in:
parent
4550cd2cd6
commit
a243983242
|
@ -383,11 +383,12 @@ static bool isComplexType(const Variable* var, const Token* varTypeTok)
|
||||||
if (knownTypes.empty()) {
|
if (knownTypes.empty()) {
|
||||||
knownTypes.insert("struct"); // If a type starts with the struct keyword, its a complex type
|
knownTypes.insert("struct"); // If a type starts with the struct keyword, its a complex type
|
||||||
knownTypes.insert("string");
|
knownTypes.insert("string");
|
||||||
|
knownTypes.insert("wstring");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (varTypeTok->str() == "std")
|
if (varTypeTok->str() == "std")
|
||||||
varTypeTok = varTypeTok->tokAt(2);
|
varTypeTok = varTypeTok->tokAt(2);
|
||||||
return(knownTypes.find(varTypeTok->str()) != knownTypes.end() && !var->isPointer() && !var->isArray());
|
return((knownTypes.find(varTypeTok->str()) != knownTypes.end() || (varTypeTok->strAt(1) == "<" && varTypeTok->linkAt(1) && varTypeTok->linkAt(1)->strAt(1) != "::")) && !var->isPointer() && !var->isArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isKnownType(const Variable* var, const Token* varTypeTok)
|
static bool isKnownType(const Variable* var, const Token* varTypeTok)
|
||||||
|
|
|
@ -870,9 +870,9 @@ void CheckOther::switchCaseFallThrough(const Token *tok)
|
||||||
//
|
//
|
||||||
// int y = y; // <- redundant initialization to self
|
// int y = y; // <- redundant initialization to self
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
static bool isPOD(const Tokenizer *tokenizer, const Variable* var)
|
static bool isTypeWithoutSideEffects(const Tokenizer *tokenizer, const Variable* var)
|
||||||
{
|
{
|
||||||
return ((var && (!var->isClass() || var->isPointer())) || !tokenizer->isCPP());
|
return ((var && (!var->isClass() || var->isPointer()) || Token::simpleMatch(var->typeStartToken(), "std ::")) || !tokenizer->isCPP());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckOther::checkSelfAssignment()
|
void CheckOther::checkSelfAssignment()
|
||||||
|
@ -887,7 +887,7 @@ void CheckOther::checkSelfAssignment()
|
||||||
while (tok) {
|
while (tok) {
|
||||||
if (Token::Match(tok->previous(), "[;{}]") &&
|
if (Token::Match(tok->previous(), "[;{}]") &&
|
||||||
tok->varId() && tok->varId() == tok->tokAt(2)->varId() &&
|
tok->varId() && tok->varId() == tok->tokAt(2)->varId() &&
|
||||||
isPOD(_tokenizer, symbolDatabase->getVariableFromVarId(tok->varId()))) {
|
isTypeWithoutSideEffects(_tokenizer, symbolDatabase->getVariableFromVarId(tok->varId()))) {
|
||||||
bool err = true;
|
bool err = true;
|
||||||
|
|
||||||
// no false positive for 'x = x ? x : 1;'
|
// no false positive for 'x = x ? x : 1;'
|
||||||
|
@ -1567,7 +1567,7 @@ void CheckOther::checkVariableScope()
|
||||||
|
|
||||||
for (unsigned int i = 1; i < symbolDatabase->getVariableListSize(); i++) {
|
for (unsigned int i = 1; i < symbolDatabase->getVariableListSize(); i++) {
|
||||||
const Variable* var = symbolDatabase->getVariableFromVarId(i);
|
const Variable* var = symbolDatabase->getVariableFromVarId(i);
|
||||||
if (!var || !var->isLocal() || (!var->typeStartToken()->isStandardType() && !var->typeStartToken()->next()->isStandardType()))
|
if (!var || !var->isLocal() || (!var->isPointer() && !var->typeStartToken()->isStandardType() && !var->typeStartToken()->next()->isStandardType()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bool forHead = false; // Don't check variables declared in header of a for loop
|
bool forHead = false; // Don't check variables declared in header of a for loop
|
||||||
|
@ -1758,7 +1758,7 @@ static bool isChar(const Variable* var)
|
||||||
|
|
||||||
static bool isSignedChar(const Variable* var)
|
static bool isSignedChar(const Variable* var)
|
||||||
{
|
{
|
||||||
return(isChar(var) && !var->typeEndToken()->isUnsigned() && (!var->typeEndToken()->previous() || !var->typeEndToken()->previous()->isUnsigned()));
|
return(isChar(var) && !var->typeStartToken()->isUnsigned());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckOther::checkCharVariable()
|
void CheckOther::checkCharVariable()
|
||||||
|
@ -2176,7 +2176,7 @@ void CheckOther::checkDuplicateIf()
|
||||||
expressionMap.insert(std::make_pair(expression, tok));
|
expressionMap.insert(std::make_pair(expression, tok));
|
||||||
|
|
||||||
// find the next else if (...) statement
|
// find the next else if (...) statement
|
||||||
const Token *tok1 = tok->next()->link()->next()->link();
|
const Token *tok1 = scope->classEnd;
|
||||||
|
|
||||||
// check all the else if (...) statements
|
// check all the else if (...) statements
|
||||||
while (Token::simpleMatch(tok1, "} else if (") &&
|
while (Token::simpleMatch(tok1, "} else if (") &&
|
||||||
|
|
|
@ -2306,7 +2306,7 @@ private:
|
||||||
"{\n"
|
"{\n"
|
||||||
" std::string var = var = \"test\";\n"
|
" std::string var = var = \"test\";\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
TODO_ASSERT_EQUALS("[test.cpp:3]: (warning) Redundant assignment of \"var\" to itself\n", "", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (warning) Redundant assignment of \"var\" to itself\n", errout.str());
|
||||||
|
|
||||||
check("void foo()\n"
|
check("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
|
Loading…
Reference in New Issue