Refactorization: Moved detection of STL strings to SymbolDatabase

This commit is contained in:
PKEuS 2014-09-05 12:03:08 +02:00
parent 4940da06c0
commit e8f7279039
8 changed files with 31 additions and 20 deletions

View File

@ -779,7 +779,7 @@ void CheckClass::initializationListUsage()
}
if (!allowed)
continue;
if (!var->isPointer() && !var->isReference() && (var->type() || Token::Match(var->typeStartToken(), "std :: string|wstring !!::") || (Token::Match(var->typeStartToken(), "std :: %type% <") && !Token::simpleMatch(var->typeStartToken()->linkAt(3), "> ::"))))
if (!var->isPointer() && !var->isReference() && (var->type() || var->isStlStringType() || (Token::Match(var->typeStartToken(), "std :: %type% <") && !Token::simpleMatch(var->typeStartToken()->linkAt(3), "> ::"))))
suggestInitializationList(tok, tok->str());
}
}

View File

@ -1616,17 +1616,11 @@ bool CheckIO::ArgumentInfo::isComplexType() const
if (variableInfo->type())
return (true);
static std::set<std::string> knownTypes;
if (knownTypes.empty()) {
knownTypes.insert("string");
knownTypes.insert("wstring");
}
const Token* varTypeTok = typeToken;
if (varTypeTok->str() == "std")
varTypeTok = varTypeTok->tokAt(2);
return ((knownTypes.find(varTypeTok->str()) != knownTypes.end() || (varTypeTok->strAt(1) == "<" && varTypeTok->linkAt(1) && varTypeTok->linkAt(1)->strAt(1) != "::")) && !variableInfo->isArrayOrPointer());
return ((variableInfo->isStlStringType() || (varTypeTok->strAt(1) == "<" && varTypeTok->linkAt(1) && varTypeTok->linkAt(1)->strAt(1) != "::")) && !variableInfo->isArrayOrPointer());
}
bool CheckIO::ArgumentInfo::isKnownType() const

View File

@ -187,7 +187,7 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown)
return true;
if (Token::Match(parent->previous(), "%var% (") && tok->strAt(1) == ")") {
const Variable* var = tok->tokAt(-2)->variable();
if (var && !var->isPointer() && !var->isArray() && Token::Match(var->typeStartToken(), "std :: string|wstring !!::"))
if (var && !var->isPointer() && !var->isArray() && var->isStlStringType())
return true;
}
@ -217,7 +217,7 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown)
else if (parent->astOperand1() && parent->astOperand2() == tok)
ovar = parent->astOperand1()->variable();
}
if (ovar && !ovar->isPointer() && !ovar->isArray() && Token::Match(ovar->typeStartToken(), "std :: string|wstring !!::"))
if (ovar && !ovar->isPointer() && !ovar->isArray() && ovar->isStlStringType())
return true;
// assume that it's not a dereference (no false positives)
@ -391,7 +391,7 @@ void CheckNullPointer::nullConstantDereference()
else if (Token::Match(tok->previous(), "!!. %var% (") && (tok->previous()->str() != "::" || tok->strAt(-2) == "std")) {
if (Token::simpleMatch(tok->tokAt(2), "0 )") && tok->varId()) { // constructor call
const Variable *var = tok->variable();
if (var && !var->isPointer() && !var->isArray() && Token::Match(var->typeStartToken(), "std :: string|wstring !!::"))
if (var && !var->isPointer() && !var->isArray() && var->isStlStringType())
nullPointerError(tok);
} else { // function call
std::list<const Token *> var;
@ -431,7 +431,7 @@ void CheckNullPointer::nullConstantDereference()
ovar = tok->variable();
else if (Token::Match(tok, "%var% =|+ 0 )|]|,|;|+"))
ovar = tok->variable();
if (ovar && !ovar->isPointer() && !ovar->isArray() && Token::Match(ovar->typeStartToken(), "std :: string|wstring !!::"))
if (ovar && !ovar->isPointer() && !ovar->isArray() && ovar->isStlStringType())
nullPointerError(tok);
}
}

View File

@ -1608,9 +1608,9 @@ void CheckOther::checkConstantFunctionParameter()
// namespace and add them to the pattern. There are
// streams for example (however it seems strange with
// const stream parameter).
if (Token::Match(tok, "std :: string|wstring !!::")) {
if (var->isStlStringType()) {
passedByValueError(tok, var->name());
} else if (Token::Match(tok, "std :: %type% <") && !Token::simpleMatch(tok->linkAt(3), "> ::")) {
} else if (var->isStlType() && Token::Match(tok, "std :: %type% <") && !Token::simpleMatch(tok->linkAt(3), "> ::")) {
passedByValueError(tok, var->name());
} else if (var->type()) { // Check if type is a struct or class.
passedByValueError(tok, var->name());

View File

@ -801,7 +801,7 @@ void CheckStl::if_find()
const Token * decl = var->typeStartToken();
const unsigned int varid = tok->varId();
bool str = Token::Match(decl, "std :: string|wstring &| %varid%", varid);
bool str = var->isStlStringType() && !var->isArrayOrPointer();
if (if_findCompare(tok->linkAt(3), str))
continue;
@ -858,7 +858,7 @@ void CheckStl::if_find()
if_findError(tok, true);
}
else if (decl && decl->str() == "string") {
else if (var->isStlStringType()) {
decl = decl->next();
if ((Token::Match(decl, "* &| %varid%", varid) ||
Token::Match(decl, "&| %varid% [ ]| %any% ]| ", varid)) && performance)

View File

@ -1174,6 +1174,7 @@ void Variable::evaluate()
if (_start) {
setFlag(fIsClass, !_start->isStandardType() && !isPointer() && !isReference());
setFlag(fIsStlType, Token::simpleMatch(_start, "std ::"));
setFlag(fIsStlString, isStlType() && (Token::Match(_start->tokAt(2), "string|wstring|u16string|u32string !!::") || (Token::simpleMatch(_start->tokAt(2), "basic_string <") && !Token::simpleMatch(_start->linkAt(3), "> ::"))));
}
if (_access == Argument) {
tok = _name;

View File

@ -137,8 +137,9 @@ class CPPCHECKLIB Variable {
fIsRValueRef = (1 << 8), /** @brief rvalue reference variable */
fHasDefault = (1 << 9), /** @brief function argument with default value */
fIsStlType = (1 << 10), /** @brief STL type ('std::') */
fIsIntType = (1 << 11), /** @brief Integral type */
fIsFloatType = (1 << 12) /** @brief Floating point type */
fIsStlString = (1 << 11), /** @brief std::string|wstring|basic_string<T>|u16string|u32string */
fIsIntType = (1 << 12), /** @brief Integral type */
fIsFloatType = (1 << 13) /** @brief Floating point type */
};
/**
@ -446,6 +447,18 @@ public:
return _dimensions[index_].known;
}
/**
* Checks if the variable is an STL type ('std::')
* E.g.:
* std::string s;
* ...
* sVar->isStlType() == true
* @return true if it is an stl type and its type matches any of the types in 'stlTypes'
*/
bool isStlType() const {
return getFlag(fIsStlType);
}
/**
* Checks if the variable is an STL type ('std::')
* E.g.:
@ -454,8 +467,8 @@ public:
* sVar->isStlType() == true
* @return true if it is an stl type and its type matches any of the types in 'stlTypes'
*/
bool isStlType() const {
return getFlag(fIsStlType);
bool isStlStringType() const {
return getFlag(fIsStlString);
}
/**

View File

@ -640,6 +640,7 @@ private:
ASSERT_EQUALS(true, v.isStlType());
ASSERT_EQUALS(true, v.isStlType(types));
ASSERT_EQUALS(false, v.isStlType(no_types));
ASSERT_EQUALS(true, v.isStlStringType());
}
{
reset();
@ -655,6 +656,7 @@ private:
ASSERT_EQUALS(true, v.isStlType());
ASSERT_EQUALS(true, v.isStlType(types));
ASSERT_EQUALS(false, v.isStlType(no_types));
ASSERT_EQUALS(false, v.isStlStringType());
}
{
reset();
@ -667,6 +669,7 @@ private:
const char* types[] = { "bitset", "set", "vector" };
ASSERT_EQUALS(false, v.isStlType());
ASSERT_EQUALS(false, v.isStlType(types));
ASSERT_EQUALS(false, v.isStlStringType());
}
}