Cppcheck
checktype.cpp
Go to the documentation of this file.
1 /*
2  * Cppcheck - A tool for static C/C++ code analysis
3  * Copyright (C) 2007-2024 Cppcheck team.
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 
20 //---------------------------------------------------------------------------
21 #include "checktype.h"
22 
23 #include "errortypes.h"
24 #include "mathlib.h"
25 #include "platform.h"
26 #include "settings.h"
27 #include "standards.h"
28 #include "symboldatabase.h"
29 #include "token.h"
30 #include "tokenize.h"
31 #include "valueflow.h"
32 
33 #include <algorithm>
34 #include <cmath>
35 #include <cstddef>
36 #include <iterator>
37 #include <list>
38 #include <sstream>
39 #include <utility>
40 #include <vector>
41 
42 //---------------------------------------------------------------------------
43 
44 // Register this check class (by creating a static instance of it)
45 namespace {
46  CheckType instance;
47 }
48 
49 //---------------------------------------------------------------------------
50 // Checking for shift by too many bits
51 //---------------------------------------------------------------------------
52 //
53 
54 // CWE ids used:
55 static const CWE CWE195(195U); // Signed to Unsigned Conversion Error
56 static const CWE CWE197(197U); // Numeric Truncation Error
57 static const CWE CWE758(758U); // Reliance on Undefined, Unspecified, or Implementation-Defined Behavior
58 static const CWE CWE190(190U); // Integer Overflow or Wraparound
59 
60 
62 {
63  // unknown sizeof(int) => can't run this checker
64  if (mSettings->platform.type == Platform::Type::Unspecified)
65  return;
66 
67  logChecker("CheckType::checkTooBigBitwiseShift"); // platform
68 
69  for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
70  // C++ and macro: OUT(x<<y)
71  if (tok->isCpp() && Token::Match(tok, "[;{}] %name% (") && Token::simpleMatch(tok->linkAt(2), ") ;") && tok->next()->isUpperCaseName() && !tok->next()->function())
72  tok = tok->linkAt(2);
73 
74  if (!tok->astOperand1() || !tok->astOperand2())
75  continue;
76 
77  if (!Token::Match(tok, "<<|>>|<<=|>>="))
78  continue;
79 
80  // get number of bits of lhs
81  const ValueType * const lhstype = tok->astOperand1()->valueType();
82  if (!lhstype || !lhstype->isIntegral() || lhstype->pointer >= 1)
83  continue;
84  // C11 Standard, section 6.5.7 Bitwise shift operators, states:
85  // The integer promotions are performed on each of the operands.
86  // The type of the result is that of the promoted left operand.
87  int lhsbits;
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))
93  lhsbits = mSettings->platform.int_bit;
94  else if (lhstype->type == ValueType::Type::LONG)
95  lhsbits = mSettings->platform.long_bit;
96  else if (lhstype->type == ValueType::Type::LONGLONG)
97  lhsbits = mSettings->platform.long_long_bit;
98  else
99  continue;
100 
101  // Get biggest rhs value. preferably a value which doesn't have 'condition'.
102  const ValueFlow::Value * value = tok->astOperand2()->getValueGE(lhsbits, *mSettings);
103  if (value && mSettings->isEnabled(value, false))
104  tooBigBitwiseShiftError(tok, lhsbits, *value);
105  else if (lhstype->sign == ValueType::Sign::SIGNED) {
106  value = tok->astOperand2()->getValueGE(lhsbits-1, *mSettings);
107  if (value && mSettings->isEnabled(value, false))
108  tooBigSignedBitwiseShiftError(tok, lhsbits, *value);
109  }
110  }
111 }
112 
113 void CheckType::tooBigBitwiseShiftError(const Token *tok, int lhsbits, const ValueFlow::Value &rhsbits)
114 {
115  constexpr char id[] = "shiftTooManyBits";
116 
117  if (!tok) {
118  reportError(tok, Severity::error, id, "Shifting 32-bit value by 40 bits is undefined behaviour", CWE758, Certainty::normal);
119  return;
120  }
121 
122  const ErrorPath errorPath = getErrorPath(tok, &rhsbits, "Shift");
123 
124  std::ostringstream errmsg;
125  errmsg << "Shifting " << lhsbits << "-bit value by " << rhsbits.intvalue << " bits is undefined behaviour";
126  if (rhsbits.condition)
127  errmsg << ". See condition at line " << rhsbits.condition->linenr() << ".";
128 
130 }
131 
132 void CheckType::tooBigSignedBitwiseShiftError(const Token *tok, int lhsbits, const ValueFlow::Value &rhsbits)
133 {
134  constexpr char id[] = "shiftTooManyBitsSigned";
135 
136  const bool cpp14 = ((tok && tok->isCpp()) || (mTokenizer && mTokenizer->isCPP())) && (mSettings->standards.cpp >= Standards::CPP14);
137 
138  std::string behaviour = "undefined";
139  if (cpp14)
140  behaviour = "implementation-defined";
141  if (!tok) {
142  reportError(tok, Severity::error, id, "Shifting signed 32-bit value by 31 bits is " + behaviour + " behaviour", CWE758, Certainty::normal);
143  return;
144  }
145 
146 
147  Severity severity = rhsbits.errorSeverity() ? Severity::error : Severity::warning;
148  if (cpp14)
149  severity = Severity::portability;
150 
152  return;
153  const ErrorPath errorPath = getErrorPath(tok, &rhsbits, "Shift");
154 
155  std::ostringstream errmsg;
156  errmsg << "Shifting signed " << lhsbits << "-bit value by " << rhsbits.intvalue << " bits is " + behaviour + " behaviour";
157  if (rhsbits.condition)
158  errmsg << ". See condition at line " << rhsbits.condition->linenr() << ".";
159 
160  reportError(errorPath, severity, id, errmsg.str(), CWE758, rhsbits.isInconclusive() ? Certainty::inconclusive : Certainty::normal);
161 }
162 
163 //---------------------------------------------------------------------------
164 // Checking for integer overflow
165 //---------------------------------------------------------------------------
166 
168 {
169  // unknown sizeof(int) => can't run this checker
170  if (mSettings->platform.type == Platform::Type::Unspecified || mSettings->platform.int_bit >= MathLib::bigint_bits)
171  return;
172 
173  logChecker("CheckType::checkIntegerOverflow"); // platform
174 
175  for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
176  if (!tok->isArithmeticalOp())
177  continue;
178 
179  // is result signed integer?
180  const ValueType *vt = tok->valueType();
181  if (!vt || !vt->isIntegral() || vt->sign != ValueType::Sign::SIGNED)
182  continue;
183 
184  unsigned int bits;
185  if (vt->type == ValueType::Type::INT)
186  bits = mSettings->platform.int_bit;
187  else if (vt->type == ValueType::Type::LONG)
188  bits = mSettings->platform.long_bit;
189  else if (vt->type == ValueType::Type::LONGLONG)
191  else
192  continue;
193 
194  if (bits >= MathLib::bigint_bits)
195  continue;
196 
197  // max value according to platform settings.
198  const MathLib::bigint maxvalue = (((MathLib::biguint)1) << (bits - 1)) - 1;
199 
200  // is there a overflow result value
201  const ValueFlow::Value *value = tok->getValueGE(maxvalue + 1, *mSettings);
202  if (!value)
203  value = tok->getValueLE(-maxvalue - 2, *mSettings);
204  if (!value || !mSettings->isEnabled(value,false))
205  continue;
206 
207  // For left shift, it's common practice to shift into the sign bit
208  if (tok->str() == "<<" && value->intvalue > 0 && value->intvalue < (((MathLib::bigint)1) << bits))
209  continue;
210 
211  integerOverflowError(tok, *value);
212  }
213 }
214 
216 {
217  const std::string expr(tok ? tok->expressionString() : "");
218 
219  std::string msg;
220  if (value.condition)
222  " or there is signed integer overflow for expression '" + expr + "'.";
223  else
224  msg = "Signed integer overflow for expression '" + expr + "'.";
225 
226  if (value.safe)
227  msg = "Safe checks: " + msg;
228 
229  reportError(getErrorPath(tok, &value, "Integer overflow"),
231  getMessageId(value, "integerOverflow").c_str(),
232  msg,
233  CWE190,
235 }
236 
237 //---------------------------------------------------------------------------
238 // Checking for sign conversion when operand can be negative
239 //---------------------------------------------------------------------------
240 
242 {
244  return;
245 
246  logChecker("CheckType::checkSignConversion"); // warning
247 
248  for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
249  if (!tok->isArithmeticalOp() || Token::Match(tok,"+|-"))
250  continue;
251 
252  // Is result unsigned?
253  if (!(tok->valueType() && tok->valueType()->sign == ValueType::Sign::UNSIGNED))
254  continue;
255 
256  // Check if an operand can be negative..
257  const Token * astOperands[] = { tok->astOperand1(), tok->astOperand2() };
258  for (const Token * tok1 : astOperands) {
259  if (!tok1)
260  continue;
261  const ValueFlow::Value* negativeValue =
262  ValueFlow::findValue(tok1->values(), *mSettings, [&](const ValueFlow::Value& v) {
263  return !v.isImpossible() && v.isIntValue() && (v.intvalue <= -1 || v.wideintvalue <= -1);
264  });
265  if (!negativeValue)
266  continue;
267  if (tok1->valueType() && tok1->valueType()->sign != ValueType::Sign::UNSIGNED)
268  signConversionError(tok1, negativeValue, tok1->isNumber());
269  }
270  }
271 }
272 
273 void CheckType::signConversionError(const Token *tok, const ValueFlow::Value *negativeValue, const bool constvalue)
274 {
275  const std::string expr(tok ? tok->expressionString() : "var");
276 
277  std::ostringstream msg;
278  if (tok && tok->isName())
279  msg << "$symbol:" << expr << "\n";
280  if (constvalue)
281  msg << "Expression '" << expr << "' has a negative value. That is converted to an unsigned value and used in an unsigned calculation.";
282  else
283  msg << "Expression '" << expr << "' can have a negative value. That is converted to an unsigned value and used in an unsigned calculation.";
284 
285  if (!negativeValue)
286  reportError(tok, Severity::warning, "signConversion", msg.str(), CWE195, Certainty::normal);
287  else {
288  const ErrorPath &errorPath = getErrorPath(tok,negativeValue,"Negative value is converted to an unsigned value");
289  reportError(errorPath,
291  Check::getMessageId(*negativeValue, "signConversion").c_str(),
292  msg.str(),
293  CWE195,
295  }
296 }
297 
298 
299 //---------------------------------------------------------------------------
300 // Checking for long cast of int result const long x = var1 * var2;
301 //---------------------------------------------------------------------------
302 static bool checkTypeCombination(ValueType src, ValueType tgt, const Settings& settings)
303 {
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 },
311  };
312 
315 
316  const std::size_t sizeSrc = ValueFlow::getSizeOf(src, settings);
317  const std::size_t sizeTgt = ValueFlow::getSizeOf(tgt, settings);
318  if (!(sizeSrc > 0 && sizeTgt > 0 && sizeSrc < sizeTgt))
319  return false;
320 
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;
323  });
324 }
325 
327 {
328  if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("truncLongCastAssignment"))
329  return;
330 
331  logChecker("CheckType::checkLongCast"); // style
332 
333  // Assignments..
334  for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
335  if (tok->str() != "=" || !Token::Match(tok->astOperand2(), "*|<<") || tok->astOperand2()->isUnaryOp("*"))
336  continue;
337 
338  if (tok->astOperand2()->hasKnownIntValue()) {
339  const ValueFlow::Value &v = tok->astOperand2()->values().front();
341  continue;
342  }
343 
344  const ValueType *lhstype = tok->astOperand1() ? tok->astOperand1()->valueType() : nullptr;
345  const ValueType *rhstype = tok->astOperand2()->valueType();
346 
347  if (!lhstype || !rhstype)
348  continue;
349  if (!checkTypeCombination(*rhstype, *lhstype, *mSettings))
350  continue;
351 
352  // assign int result to long/longlong const nonpointer?
353  if (rhstype->pointer == 0U &&
354  rhstype->originalTypeName.empty() &&
355  lhstype->pointer == 0U &&
356  lhstype->originalTypeName.empty())
357  longCastAssignError(tok, rhstype, lhstype);
358  }
359 
360  // Return..
361  const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
362  for (const Scope * scope : symbolDatabase->functionScopes) {
363 
364  // function must return long data
365  const Token * def = scope->classDef;
366  if (!Token::Match(def, "%name% (") || !def->next()->valueType())
367  continue;
368  const ValueType* retVt = def->next()->valueType();
369 
370  // return statements
371  const Token *ret = nullptr;
372  for (const Token *tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) {
373  if (tok->str() == "return") {
374  if (Token::Match(tok->astOperand1(), "<<|*")) {
375  const ValueType *type = tok->astOperand1()->valueType();
376  if (type && checkTypeCombination(*type, *retVt, *mSettings) &&
377  type->pointer == 0U &&
378  type->originalTypeName.empty())
379  ret = tok;
380  }
381  // All return statements must have problem otherwise no warning
382  if (ret != tok) {
383  ret = nullptr;
384  break;
385  }
386  }
387  }
388 
389  if (ret)
390  longCastReturnError(ret, ret->astOperand1()->valueType(), retVt);
391  }
392 }
393 
394 static void makeBaseTypeString(std::string& typeStr)
395 {
396  const auto pos = typeStr.find("signed");
397  if (pos != std::string::npos)
398  typeStr.erase(typeStr.begin(), typeStr.begin() + pos + 6 + 1);
399 }
400 
401 void CheckType::longCastAssignError(const Token *tok, const ValueType* src, const ValueType* tgt)
402 {
403  std::string srcStr = src ? src->str() : "int";
404  makeBaseTypeString(srcStr);
405  std::string tgtStr = tgt ? tgt->str() : "long";
406  makeBaseTypeString(tgtStr);
407  reportError(tok,
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);
412 }
413 
414 void CheckType::longCastReturnError(const Token *tok, const ValueType* src, const ValueType* tgt)
415 {
416  std::string srcStr = src ? src->str() : "int";
417  makeBaseTypeString(srcStr);
418  std::string tgtStr = tgt ? tgt->str() : "long";
419  makeBaseTypeString(tgtStr);
420  reportError(tok,
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);
425 }
426 
427 //---------------------------------------------------------------------------
428 // Checking for float to integer overflow
429 //---------------------------------------------------------------------------
430 
432 {
433  logChecker("CheckType::checkFloatToIntegerOverflow");
434 
435  for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
436  const ValueType *vtint, *vtfloat;
437 
438  // Explicit cast
439  if (Token::Match(tok, "( %name%") && tok->astOperand1() && !tok->astOperand2()) {
440  vtint = tok->valueType();
441  vtfloat = tok->astOperand1()->valueType();
442  checkFloatToIntegerOverflow(tok, vtint, vtfloat, tok->astOperand1()->values());
443  }
444 
445  // Assignment
446  else if (tok->str() == "=" && tok->astOperand1() && tok->astOperand2()) {
447  vtint = tok->astOperand1()->valueType();
448  vtfloat = tok->astOperand2()->valueType();
449  checkFloatToIntegerOverflow(tok, vtint, vtfloat, tok->astOperand2()->values());
450  }
451 
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)
455  scope = scope->nestedIn;
456  if (scope && scope->type == Scope::ScopeType::eFunction && scope->function && scope->function->retDef) {
457  const ValueType &valueType = ValueType::parseDecl(scope->function->retDef, *mSettings);
458  vtfloat = tok->astOperand1()->valueType();
459  checkFloatToIntegerOverflow(tok, &valueType, vtfloat, tok->astOperand1()->values());
460  }
461  }
462  }
463 }
464 
465 void CheckType::checkFloatToIntegerOverflow(const Token *tok, const ValueType *vtint, const ValueType *vtfloat, const std::list<ValueFlow::Value> &floatValues)
466 {
467  // Conversion of float to integer?
468  if (!vtint || !vtint->isIntegral())
469  return;
470  if (!vtfloat || !vtfloat->isFloat())
471  return;
472 
473  for (const ValueFlow::Value &f : floatValues) {
474  if (f.valueType != ValueFlow::Value::ValueType::FLOAT)
475  continue;
476  if (!mSettings->isEnabled(&f, false))
477  continue;
478  if (f.floatValue >= std::exp2(mSettings->platform.long_long_bit))
480  else if ((-f.floatValue) > std::exp2(mSettings->platform.long_long_bit - 1))
482  else if (mSettings->platform.type != Platform::Type::Unspecified) {
483  int bits = 0;
484  if (vtint->type == ValueType::Type::CHAR)
485  bits = mSettings->platform.char_bit;
486  else if (vtint->type == ValueType::Type::SHORT)
487  bits = mSettings->platform.short_bit;
488  else if (vtint->type == ValueType::Type::INT)
489  bits = mSettings->platform.int_bit;
490  else if (vtint->type == ValueType::Type::LONG)
491  bits = mSettings->platform.long_bit;
492  else if (vtint->type == ValueType::Type::LONGLONG)
494  else
495  continue;
496  if (bits < MathLib::bigint_bits && f.floatValue >= (((MathLib::biguint)1) << bits))
498  }
499  }
500 }
501 
503 {
504  std::ostringstream errmsg;
505  errmsg << "Undefined behaviour: float (" << value.floatValue << ") to integer conversion overflow.";
506  reportError(getErrorPath(tok, &value, "float to integer conversion"),
508  "floatConversionOverflow",
510 }
static bool checkTypeCombination(ValueType src, ValueType tgt, const Settings &settings)
Definition: checktype.cpp:302
static const CWE CWE190(190U)
static const CWE CWE758(758U)
static void makeBaseTypeString(std::string &typeStr)
Definition: checktype.cpp:394
static const CWE CWE197(197U)
static const CWE CWE195(195U)
Various small checks.
Definition: checktype.h:44
void tooBigSignedBitwiseShiftError(const Token *tok, int lhsbits, const ValueFlow::Value &rhsbits)
Definition: checktype.cpp:132
void signConversionError(const Token *tok, const ValueFlow::Value *negativeValue, const bool constvalue)
Definition: checktype.cpp:273
void checkFloatToIntegerOverflow()
Check for float to integer overflow
Definition: checktype.cpp:431
void checkIntegerOverflow()
Check for integer overflow
Definition: checktype.cpp:167
void longCastAssignError(const Token *tok, const ValueType *src=nullptr, const ValueType *tgt=nullptr)
Definition: checktype.cpp:401
void checkSignConversion()
Check for dangerous sign conversion
Definition: checktype.cpp:241
void integerOverflowError(const Token *tok, const ValueFlow::Value &value)
Definition: checktype.cpp:215
void floatToIntegerOverflowError(const Token *tok, const ValueFlow::Value &value)
Definition: checktype.cpp:502
void checkLongCast()
Check for implicit long cast of int result
Definition: checktype.cpp:326
void longCastReturnError(const Token *tok, const ValueType *src=nullptr, const ValueType *tgt=nullptr)
Definition: checktype.cpp:414
void checkTooBigBitwiseShift()
Check for bitwise shift with too big right operand
Definition: checktype.cpp:61
void tooBigBitwiseShiftError(const Token *tok, int lhsbits, const ValueFlow::Value &rhsbits)
Definition: checktype.cpp:113
void reportError(const Token *tok, const Severity severity, const std::string &id, const std::string &msg)
report an error
Definition: check.h:138
const Settings *const mSettings
Definition: check.h:134
ErrorPath getErrorPath(const Token *errtok, const ValueFlow::Value *value, std::string bug) const
Definition: check.cpp:111
const Tokenizer *const mTokenizer
Definition: check.h:133
static std::string getMessageId(const ValueFlow::Value &value, const char id[])
Definition: check.cpp:102
void logChecker(const char id[])
log checker
Definition: check.cpp:129
const Token * retDef
function return type token
long long bigint
Definition: mathlib.h:68
static const int bigint_bits
Definition: mathlib.h:70
unsigned long long biguint
Definition: mathlib.h:69
nonneg int short_bit
bits in char
Definition: platform.h:86
nonneg int int_bit
bits in short
Definition: platform.h:87
nonneg int long_bit
bits in int
Definition: platform.h:88
bool isIntValue(long long value) const
Definition: platform.h:62
nonneg int char_bit
Definition: platform.h:85
nonneg int long_long_bit
bits in long
Definition: platform.h:89
Type type
platform type
Definition: platform.h:118
ScopeType type
Function * function
function info for this function
const Scope * nestedIn
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...
Definition: settings.h:95
bool isEnabled(const ValueFlow::Value *value, bool inconclusiveCheck=false) const
Returns true if given value can be shown.
Definition: settings.cpp:274
Platform platform
Definition: settings.h:255
bool isPremiumEnabled(const char id[]) const
Is checker id enabled by premiumArgs.
Definition: settings.cpp:557
SimpleEnableGroup< Severity > severity
Definition: settings.h:358
Standards standards
Struct contains standards settings.
Definition: settings.h:366
bool isEnabled(T flag) const
Definition: settings.h:66
std::vector< const Scope * > functionScopes
Fast access to function scopes.
The token list that the TokenList generates is a linked-list of this class.
Definition: token.h:150
static bool Match(const Token *tok, const char pattern[], nonneg int varid=0)
Match given token (or list of tokens) to a pattern list.
Definition: token.cpp:722
bool isName() const
Definition: token.h:361
bool isCpp() const
Definition: token.cpp:2752
const ValueType * valueType() const
Definition: token.h:331
void astOperand1(Token *tok)
Definition: token.cpp:1490
std::string expressionString() const
Definition: token.cpp:1681
nonneg int linenr() const
Definition: token.h:816
Token * next()
Definition: token.h:830
static bool simpleMatch(const Token *tok, const char(&pattern)[count])
Match given token (or list of tokens) to a pattern list.
Definition: token.h:252
const Token * tokens() const
Definition: tokenize.h:592
const SymbolDatabase * getSymbolDatabase() const
Definition: tokenize.h:563
bool isCPP() const
Is the code CPP.
Definition: tokenize.h:69
bool errorSeverity() const
Definition: vfvalue.h:387
double floatValue
float value
Definition: vfvalue.h:274
const Token * condition
Condition that this value depends on.
Definition: vfvalue.h:280
long long intvalue
int value (or sometimes bool value?)
Definition: vfvalue.h:268
bool isInconclusive() const
Definition: vfvalue.h:378
bool safe
value relies on safe checking
Definition: vfvalue.h:290
Value type.
bool isFloat() const
enum ValueType::Type type
Reference reference
Is the outermost indirection of this type a reference or rvalue.
bool isIntegral() const
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
std::string str() const
Severity
enum class for severity.
Definition: errortypes.h:63
std::list< ErrorPathItem > ErrorPath
Definition: errortypes.h:130
@ warning
Warning.
@ portability
Portability warning.
@ style
Style warning.
@ error
Programming error.
std::string eitherTheConditionIsRedundant(const Token *condition)
Definition: valueflow.cpp:9680
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)
Definition: valueflow.cpp:1197
enum Standards::cppstd_t cpp