Refactorized Variable::isIntegralType() and Variable::isFloatType():

- Cached property
- Make use of it in several checks
- float* is flagged as floating point type
This commit is contained in:
PKEuS 2014-08-09 11:44:55 +02:00
parent 2d06786c3f
commit 5d302716e7
7 changed files with 26 additions and 14 deletions

View File

@ -39,7 +39,7 @@ static bool isaddr(const Variable *var)
/** Is given variable an integer variable */
static bool isint(const Variable *var)
{
return (var && Token::Match(var->nameToken()->previous(), "int|long|DWORD %var% !!["));
return (var && var->isIntegralType() && !var->isArrayOrPointer());
}
void Check64BitPortability::pointerassignment()

View File

@ -487,7 +487,7 @@ void CheckBool::checkAssignBoolToFloat()
for (const Token* tok = scope->classStart; tok != scope->classEnd; tok = tok->next()) {
if (Token::Match(tok, "%var% =")) {
const Variable * const var = symbolDatabase->getVariableFromVarId(tok->varId());
if (var && var->isFloatingType() && astIsBool(tok->next()->astOperand2()))
if (var && var->isFloatingType() && !var->isArrayOrPointer() && astIsBool(tok->next()->astOperand2()))
assignBoolToFloatError(tok->next());
}
}

View File

@ -1058,7 +1058,7 @@ void CheckClass::checkMemsetType(const Scope *start, const Token *tok, const Sco
checkMemsetType(start, tok, typeScope, allocation, parsedTypes);
// check for float
else if ((var->typeStartToken()->str() == "float" || var->typeStartToken()->str() == "double") && _settings->isEnabled("portability"))
else if (var->isFloatingType() && _settings->isEnabled("portability"))
memsetErrorFloat(tok, tok->str(), type->classDef->str());
}
}

View File

@ -47,7 +47,7 @@ static bool astIsFloat(const Token *tok, bool unknown)
if (!tok->variable())
return unknown;
return Token::findmatch(tok->variable()->typeStartToken(), "float|double", tok->variable()->typeEndToken()->next(), 0) != nullptr;
return tok->variable()->isFloatingType();
}
if (tok->isOp())
@ -1602,7 +1602,7 @@ bool CheckOther::isUnsigned(const Variable* var) const
}
bool CheckOther::isSigned(const Variable* var)
{
return (var && !var->typeStartToken()->isUnsigned() && Token::Match(var->typeEndToken(), "int|char|short|long") && !var->isPointer() && !var->isArray());
return (var && !var->typeStartToken()->isUnsigned() && var->isIntegralType() && !var->isPointer() && !var->isArray());
}
void CheckOther::checkUnsignedDivision()
@ -2077,7 +2077,7 @@ void CheckOther::checkCharVariable()
if (!lhs || !lhs->isName())
continue;
const Variable *var = lhs->variable();
if (var && Token::Match(var->typeStartToken(), "short|int|long"))
if (var && var->isIntegralType() && var->typeStartToken()->str() != "char")
charBitOpError(tok); // This is an error..
}
}

View File

@ -1203,6 +1203,13 @@ void Variable::evaluate()
if (Token::Match(_name, "%var% ; %var% = %any% ;") && _name->strAt(2) == _name->str())
setFlag(fHasDefault, true);
}
if (_start) {
if (_start->str() == "bool" || _start->str() == "char" || _start->str() == "short" || _start->str() == "int" || _start->str() == "long")
setFlag(fIsIntType, true);
else if (_start->str() == "float" || _start->str() == "double")
setFlag(fIsFloatType, true);
}
}
bool Function::argsMatch(const Scope *scope, const Token *first, const Token *second, const std::string &path, unsigned int depth)

View File

@ -136,7 +136,9 @@ class CPPCHECKLIB Variable {
fIsReference = (1 << 7), /** @brief reference variable */
fIsRValueRef = (1 << 8), /** @brief rvalue reference variable */
fHasDefault = (1 << 9), /** @brief function argument with default value */
fIsStlType = (1 << 10) /** @brief STL type ('std::') */
fIsStlType = (1 << 10), /** @brief STL type ('std::') */
fIsIntType = (1 << 11), /** @brief Integral type */
fIsFloatType = (1 << 12) /** @brief Floating point type */
};
/**
@ -473,18 +475,18 @@ public:
/**
* Determine whether it's a floating number type
* @return true if the type is known and it's a floating type (float, double and long double)
* @return true if the type is known and it's a floating type (float, double and long double) or a pointer/array to it
*/
bool isFloatingType() const {
return (typeStartToken()->str() == "float" || typeStartToken()->str() == "double") && !isArrayOrPointer() ;
return getFlag(fIsFloatType);
}
/**
* Determine whether it's an integral number type
* @return true if the type is known and it's an integral type (bool, char, short, int, long long and their unsigned counter parts)
* @return true if the type is known and it's an integral type (bool, char, short, int, long long and their unsigned counter parts) or a pointer/array to it
*/
bool isIntegralType() const {
return typeStartToken()->str() == "bool" || typeStartToken()->str() == "char" || typeStartToken()->str() == "short" || typeStartToken()->str() == "int" || typeStartToken()->str() == "long";
return getFlag(fIsIntType);
}

View File

@ -2416,14 +2416,16 @@ private:
if (f) {
ASSERT_EQUALS("f", f->nameToken()->str());
ASSERT_EQUALS(false, f->isIntegralType());
ASSERT_EQUALS(false, f->isFloatingType());
ASSERT_EQUALS(true, f->isFloatingType());
ASSERT_EQUALS(true, f->isArrayOrPointer());
}
const Variable *scf = db->getVariableFromVarId(2);
ASSERT(scf != nullptr);
if (scf) {
ASSERT_EQUALS("scf", scf->nameToken()->str());
ASSERT_EQUALS(false, scf->isIntegralType());
ASSERT_EQUALS(false, scf->isFloatingType());
ASSERT_EQUALS(true, scf->isFloatingType());
ASSERT_EQUALS(true, scf->isArrayOrPointer());
}
}
{
@ -2433,7 +2435,8 @@ private:
if (fa) {
ASSERT_EQUALS("fa", fa->nameToken()->str());
ASSERT_EQUALS(false, fa->isIntegralType());
ASSERT_EQUALS(false, fa->isFloatingType());
ASSERT_EQUALS(true, fa->isFloatingType());
ASSERT_EQUALS(true, fa->isArrayOrPointer());
}
}
}