67     logChecker(
"CheckType::checkTooBigBitwiseShift"); 
 
   71         if (tok->isCpp() && 
Token::Match(tok, 
"[;{}] %name% (") && 
Token::simpleMatch(tok->linkAt(2), 
") ;") && tok->next()->isUpperCaseName() && !tok->next()->function())
 
   74         if (!tok->astOperand1() || !tok->astOperand2())
 
   81         const ValueType * 
const lhstype = tok->astOperand1()->valueType();
 
   88         if ((lhstype->
type == ValueType::Type::CHAR) ||
 
   89             (lhstype->
type == ValueType::Type::SHORT) ||
 
   90             (lhstype->
type == ValueType::Type::WCHAR_T) ||
 
   91             (lhstype->
type == ValueType::Type::BOOL) ||
 
   92             (lhstype->
type == ValueType::Type::INT))
 
   94         else if (lhstype->
type == ValueType::Type::LONG)
 
   96         else if (lhstype->
type == ValueType::Type::LONGLONG)
 
  105         else if (lhstype->
sign == ValueType::Sign::SIGNED) {
 
  106             value = tok->astOperand2()->getValueGE(lhsbits-1, *
mSettings);
 
  115     constexpr 
char id[] = 
"shiftTooManyBits";
 
  124     std::ostringstream errmsg;
 
  125     errmsg << 
"Shifting " << lhsbits << 
"-bit value by " << rhsbits.
intvalue << 
" bits is undefined behaviour";
 
  127         errmsg << 
". See condition at line " << rhsbits.
condition->
linenr() << 
".";
 
  134     constexpr 
char id[] = 
"shiftTooManyBitsSigned";
 
  138     std::string behaviour = 
"undefined";
 
  140         behaviour = 
"implementation-defined";
 
  155     std::ostringstream errmsg;
 
  156     errmsg << 
"Shifting signed " << lhsbits << 
"-bit value by " << rhsbits.
intvalue << 
" bits is " + behaviour + 
" behaviour";
 
  158         errmsg << 
". See condition at line " << rhsbits.
condition->
linenr() << 
".";
 
  173     logChecker(
"CheckType::checkIntegerOverflow"); 
 
  176         if (!tok->isArithmeticalOp())
 
  181         if (!vt || !vt->
isIntegral() || vt->
sign != ValueType::Sign::SIGNED)
 
  185         if (vt->
type == ValueType::Type::INT)
 
  187         else if (vt->
type == ValueType::Type::LONG)
 
  189         else if (vt->
type == ValueType::Type::LONGLONG)
 
  203             value = tok->getValueLE(-maxvalue - 2, *
mSettings);
 
  222               " or there is signed integer overflow for expression '" + expr + 
"'.";
 
  224         msg = 
"Signed integer overflow for expression '" + expr + 
"'.";
 
  227         msg = 
"Safe checks: " + msg;
 
  249         if (!tok->isArithmeticalOp() || 
Token::Match(tok,
"+|-"))
 
  253         if (!(tok->valueType() && tok->valueType()->sign == ValueType::Sign::UNSIGNED))
 
  258         for (
const Token * tok1 : astOperands) {
 
  263                 return !v.isImpossible() && v.isIntValue() && (v.intvalue <= -1 || v.wideintvalue <= -1);
 
  267             if (tok1->valueType() && tok1->valueType()->sign != ValueType::Sign::UNSIGNED)
 
  277     std::ostringstream msg;
 
  279         msg << 
"$symbol:" << expr << 
"\n";
 
  281         msg << 
"Expression '" << expr << 
"' has a negative value. That is converted to an unsigned value and used in an unsigned calculation.";
 
  283         msg << 
"Expression '" << expr << 
"' can have a negative value. That is converted to an unsigned value and used in an unsigned calculation.";
 
  288         const ErrorPath &errorPath = 
getErrorPath(tok,negativeValue,
"Negative value is converted to an unsigned value");
 
  304     static const std::pair<ValueType::Type, ValueType::Type> typeCombinations[] = {
 
  305         { ValueType::Type::INT, ValueType::Type::LONG },
 
  306         { ValueType::Type::INT, ValueType::Type::LONGLONG },
 
  307         { ValueType::Type::LONG, ValueType::Type::LONGLONG },
 
  308         { ValueType::Type::FLOAT, ValueType::Type::DOUBLE },
 
  309         { ValueType::Type::FLOAT, ValueType::Type::LONGDOUBLE },
 
  310         { ValueType::Type::DOUBLE, ValueType::Type::LONGDOUBLE },
 
  318     if (!(sizeSrc > 0 && sizeTgt > 0 && sizeSrc < sizeTgt))
 
  321     return std::any_of(std::begin(typeCombinations), std::end(typeCombinations), [&](
const std::pair<ValueType::Type, ValueType::Type>& p) {
 
  322         return src.
type == p.first && tgt.
type == p.second;
 
  335         if (tok->str() != 
"=" || !
Token::Match(tok->astOperand2(), 
"*|<<") || tok->astOperand2()->isUnaryOp(
"*"))
 
  338         if (tok->astOperand2()->hasKnownIntValue()) {
 
  344         const ValueType *lhstype = tok->astOperand1() ? tok->astOperand1()->valueType() : 
nullptr;
 
  345         const ValueType *rhstype = tok->astOperand2()->valueType();
 
  347         if (!lhstype || !rhstype)
 
  371         const Token *ret = 
nullptr;
 
  373             if (tok->str() == 
"return") {
 
  375                     const ValueType *type = tok->astOperand1()->valueType();
 
  396     const auto pos = typeStr.find(
"signed");
 
  397     if (pos != std::string::npos)
 
  398         typeStr.erase(typeStr.begin(), typeStr.begin() + pos + 6 + 1);
 
  403     std::string srcStr = src ? src->
str() : 
"int";
 
  405     std::string tgtStr = tgt ? tgt->
str() : 
"long";
 
  409                 "truncLongCastAssignment",
 
  410                 srcStr + 
" result is assigned to " + tgtStr + 
" variable. If the variable is " + tgtStr + 
" to avoid loss of information, then you have loss of information.\n" +
 
  411                 srcStr + 
" result is assigned to " + tgtStr + 
" variable. If the variable is " + tgtStr + 
" to avoid loss of information, then there is loss of information. To avoid loss of information you must cast a calculation operand to " + tgtStr + 
", for example 'l = a * b;' => 'l = (" + tgtStr + 
")a * b;'.", 
CWE197, 
Certainty::normal);
 
  416     std::string srcStr = src ? src->
str() : 
"int";
 
  418     std::string tgtStr = tgt ? tgt->
str() : 
"long";
 
  422                 "truncLongCastReturn",
 
  423                 srcStr +
" result is returned as " + tgtStr + 
" value. If the return value is " + tgtStr + 
" to avoid loss of information, then you have loss of information.\n" +
 
  424                 srcStr +
" result is returned as " + tgtStr + 
" value. If the return value is " + tgtStr + 
" to avoid loss of information, then there is loss of information. To avoid loss of information you must cast a calculation operand to long, for example 'return a*b;' => 'return (long)a*b'.", 
CWE197, 
Certainty::normal);
 
  433     logChecker(
"CheckType::checkFloatToIntegerOverflow");
 
  439         if (
Token::Match(tok, 
"( %name%") && tok->astOperand1() && !tok->astOperand2()) {
 
  440             vtint = tok->valueType();
 
  441             vtfloat = tok->astOperand1()->valueType();
 
  446         else if (tok->str() == 
"=" && tok->astOperand1() && tok->astOperand2()) {
 
  447             vtint = tok->astOperand1()->valueType();
 
  448             vtfloat = tok->astOperand2()->valueType();
 
  452         else if (tok->str() == 
"return" && tok->astOperand1() && tok->astOperand1()->valueType() && tok->astOperand1()->valueType()->isFloat()) {
 
  453             const Scope *scope = tok->scope();
 
  454             while (scope && scope->
type != Scope::ScopeType::eLambda && scope->
type != Scope::ScopeType::eFunction)
 
  458                 vtfloat = tok->astOperand1()->valueType();
 
  470     if (!vtfloat || !vtfloat->
isFloat())
 
  484             if (vtint->
type == ValueType::Type::CHAR)
 
  486             else if (vtint->
type == ValueType::Type::SHORT)
 
  488             else if (vtint->
type == ValueType::Type::INT)
 
  490             else if (vtint->
type == ValueType::Type::LONG)
 
  492             else if (vtint->
type == ValueType::Type::LONGLONG)
 
  496             if (bits < MathLib::bigint_bits && f.floatValue >= (((
MathLib::biguint)1) << bits))
 
  504     std::ostringstream errmsg;
 
  505     errmsg << 
"Undefined behaviour: float (" << value.
floatValue << 
") to integer conversion overflow.";
 
  508                 "floatConversionOverflow",
 
static bool checkTypeCombination(ValueType src, ValueType tgt, const Settings &settings)
 
static const CWE CWE190(190U)
 
static const CWE CWE758(758U)
 
static void makeBaseTypeString(std::string &typeStr)
 
static const CWE CWE197(197U)
 
static const CWE CWE195(195U)
 
void tooBigSignedBitwiseShiftError(const Token *tok, int lhsbits, const ValueFlow::Value &rhsbits)
 
void signConversionError(const Token *tok, const ValueFlow::Value *negativeValue, const bool constvalue)
 
void checkFloatToIntegerOverflow()
Check for float to integer overflow
 
void checkIntegerOverflow()
Check for integer overflow
 
void longCastAssignError(const Token *tok, const ValueType *src=nullptr, const ValueType *tgt=nullptr)
 
void checkSignConversion()
Check for dangerous sign conversion
 
void integerOverflowError(const Token *tok, const ValueFlow::Value &value)
 
void floatToIntegerOverflowError(const Token *tok, const ValueFlow::Value &value)
 
void checkLongCast()
Check for implicit long cast of int result
 
void longCastReturnError(const Token *tok, const ValueType *src=nullptr, const ValueType *tgt=nullptr)
 
void checkTooBigBitwiseShift()
Check for bitwise shift with too big right operand
 
void tooBigBitwiseShiftError(const Token *tok, int lhsbits, const ValueFlow::Value &rhsbits)
 
void reportError(const Token *tok, const Severity severity, const std::string &id, const std::string &msg)
report an error
 
const Settings *const mSettings
 
ErrorPath getErrorPath(const Token *errtok, const ValueFlow::Value *value, std::string bug) const
 
const Tokenizer *const mTokenizer
 
static std::string getMessageId(const ValueFlow::Value &value, const char id[])
 
void logChecker(const char id[])
log checker
 
const Token * retDef
function return type token
 
static const int bigint_bits
 
unsigned long long biguint
 
Function * function
function info for this function
 
const Token * classDef
class/struct/union/namespace token
 
const Token * bodyStart
'{' token
 
const Token * bodyEnd
'}' token
 
This is just a container for general settings so that we don't need to pass individual values to func...
 
bool isEnabled(const ValueFlow::Value *value, bool inconclusiveCheck=false) const
Returns true if given value can be shown.
 
bool isPremiumEnabled(const char id[]) const
Is checker id enabled by premiumArgs.
 
SimpleEnableGroup< Severity > severity
 
Standards standards
Struct contains standards settings.
 
bool isEnabled(T flag) const
 
std::vector< const Scope * > functionScopes
Fast access to function scopes.
 
The token list that the TokenList generates is a linked-list of this class.
 
static bool Match(const Token *tok, const char pattern[], nonneg int varid=0)
Match given token (or list of tokens) to a pattern list.
 
const ValueType * valueType() const
 
void astOperand1(Token *tok)
 
std::string expressionString() const
 
nonneg int linenr() const
 
static bool simpleMatch(const Token *tok, const char(&pattern)[count])
Match given token (or list of tokens) to a pattern list.
 
const Token * tokens() const
 
const SymbolDatabase * getSymbolDatabase() const
 
bool isCPP() const
Is the code CPP.
 
bool errorSeverity() const
 
double floatValue
float value
 
const Token * condition
Condition that this value depends on.
 
long long intvalue
int value (or sometimes bool value?)
 
bool isInconclusive() const
 
bool safe
value relies on safe checking
 
enum ValueType::Type type
 
Reference reference
Is the outermost indirection of this type a reference or rvalue.
 
nonneg int pointer
0=>not pointer, 1=>*, 2=>**, 3=>***, etc
 
std::string originalTypeName
original type name as written in the source code.
 
static ValueType parseDecl(const Token *type, const Settings &settings)
 
enum ValueType::Sign sign
 
Severity
enum class for severity.
 
std::list< ErrorPathItem > ErrorPath
 
@ portability
Portability warning.
 
@ error
Programming error.
 
std::string eitherTheConditionIsRedundant(const Token *condition)
 
const Value * findValue(const std::list< Value > &values, const Settings &settings, const std::function< bool(const Value &)> &pred)
 
size_t getSizeOf(const ValueType &vt, const Settings &settings, int maxRecursion=0)
 
enum Standards::cppstd_t cpp