From 5d302716e7af0b8838ab241542e7d629788c0a83 Mon Sep 17 00:00:00 2001 From: PKEuS Date: Sat, 9 Aug 2014 11:44:55 +0200 Subject: [PATCH] Refactorized Variable::isIntegralType() and Variable::isFloatType(): - Cached property - Make use of it in several checks - float* is flagged as floating point type --- lib/check64bit.cpp | 2 +- lib/checkbool.cpp | 2 +- lib/checkclass.cpp | 2 +- lib/checkother.cpp | 6 +++--- lib/symboldatabase.cpp | 7 +++++++ lib/symboldatabase.h | 12 +++++++----- test/testsymboldatabase.cpp | 9 ++++++--- 7 files changed, 26 insertions(+), 14 deletions(-) diff --git a/lib/check64bit.cpp b/lib/check64bit.cpp index 9ab03e7f0..03a825cce 100644 --- a/lib/check64bit.cpp +++ b/lib/check64bit.cpp @@ -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() diff --git a/lib/checkbool.cpp b/lib/checkbool.cpp index cc45c3223..83701d46c 100644 --- a/lib/checkbool.cpp +++ b/lib/checkbool.cpp @@ -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()); } } diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 02749e50c..10da1aa92 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -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()); } } diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 609c634a0..91021b6c9 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -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.. } } diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 741a77636..57a587bf6 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -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) diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 9ed325bf4..76d69839e 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -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); } diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index fbba6df8e..9188e9054 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -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()); } } }