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 */ /** Is given variable an integer variable */
static bool isint(const Variable *var) 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() void Check64BitPortability::pointerassignment()

View File

@ -487,7 +487,7 @@ void CheckBool::checkAssignBoolToFloat()
for (const Token* tok = scope->classStart; tok != scope->classEnd; tok = tok->next()) { for (const Token* tok = scope->classStart; tok != scope->classEnd; tok = tok->next()) {
if (Token::Match(tok, "%var% =")) { if (Token::Match(tok, "%var% =")) {
const Variable * const var = symbolDatabase->getVariableFromVarId(tok->varId()); 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()); 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); checkMemsetType(start, tok, typeScope, allocation, parsedTypes);
// check for float // 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()); memsetErrorFloat(tok, tok->str(), type->classDef->str());
} }
} }

View File

@ -47,7 +47,7 @@ static bool astIsFloat(const Token *tok, bool unknown)
if (!tok->variable()) if (!tok->variable())
return unknown; return unknown;
return Token::findmatch(tok->variable()->typeStartToken(), "float|double", tok->variable()->typeEndToken()->next(), 0) != nullptr; return tok->variable()->isFloatingType();
} }
if (tok->isOp()) if (tok->isOp())
@ -1602,7 +1602,7 @@ bool CheckOther::isUnsigned(const Variable* var) const
} }
bool CheckOther::isSigned(const Variable* var) 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() void CheckOther::checkUnsignedDivision()
@ -2077,7 +2077,7 @@ void CheckOther::checkCharVariable()
if (!lhs || !lhs->isName()) if (!lhs || !lhs->isName())
continue; continue;
const Variable *var = lhs->variable(); 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.. 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()) if (Token::Match(_name, "%var% ; %var% = %any% ;") && _name->strAt(2) == _name->str())
setFlag(fHasDefault, true); 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) 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 */ fIsReference = (1 << 7), /** @brief reference variable */
fIsRValueRef = (1 << 8), /** @brief rvalue reference variable */ fIsRValueRef = (1 << 8), /** @brief rvalue reference variable */
fHasDefault = (1 << 9), /** @brief function argument with default value */ 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 * 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 { bool isFloatingType() const {
return (typeStartToken()->str() == "float" || typeStartToken()->str() == "double") && !isArrayOrPointer() ; return getFlag(fIsFloatType);
} }
/** /**
* Determine whether it's an integral number type * 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 { 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) { if (f) {
ASSERT_EQUALS("f", f->nameToken()->str()); ASSERT_EQUALS("f", f->nameToken()->str());
ASSERT_EQUALS(false, f->isIntegralType()); 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); const Variable *scf = db->getVariableFromVarId(2);
ASSERT(scf != nullptr); ASSERT(scf != nullptr);
if (scf) { if (scf) {
ASSERT_EQUALS("scf", scf->nameToken()->str()); ASSERT_EQUALS("scf", scf->nameToken()->str());
ASSERT_EQUALS(false, scf->isIntegralType()); 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) { if (fa) {
ASSERT_EQUALS("fa", fa->nameToken()->str()); ASSERT_EQUALS("fa", fa->nameToken()->str());
ASSERT_EQUALS(false, fa->isIntegralType()); ASSERT_EQUALS(false, fa->isIntegralType());
ASSERT_EQUALS(false, fa->isFloatingType()); ASSERT_EQUALS(true, fa->isFloatingType());
ASSERT_EQUALS(true, fa->isArrayOrPointer());
} }
} }
} }