Cppcheck
vfvalue.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 #include "vfvalue.h"
20 
21 #include "errortypes.h"
22 #include "token.h"
23 
24 #include <sstream>
25 #include <string>
26 
27 namespace ValueFlow {
28  Value::Value(const Token *c, long long val, Bound b)
29  : bound(b),
30  intvalue(val),
31  varvalue(val),
32  condition(c) {
33  errorPath.emplace_back(c, "Assuming that condition '" + c->expressionString() + "' is not redundant");
34  }
35 
36  void Value::assumeCondition(const Token *tok) {
37  condition = tok;
38  errorPath.emplace_back(tok, "Assuming that condition '" + tok->expressionString() + "' is not redundant");
39  }
40 
41  std::string Value::toString() const {
42  std::stringstream ss;
43  if (this->isImpossible())
44  ss << "!";
45  if (this->bound == Bound::Lower)
46  ss << ">=";
47  if (this->bound == Bound::Upper)
48  ss << "<=";
49  switch (this->valueType) {
50  case ValueType::INT:
51  ss << this->intvalue;
52  break;
53  case ValueType::TOK:
54  ss << this->tokvalue->str();
55  break;
56  case ValueType::FLOAT:
57  ss << this->floatValue;
58  break;
59  case ValueType::MOVED:
60  ss << toString(this->moveKind);
61  break;
62  case ValueType::UNINIT:
63  ss << "Uninit";
64  break;
67  ss << "size=" << this->intvalue;
68  break;
70  ss << "start=" << this->intvalue;
71  break;
73  ss << "end=" << this->intvalue;
74  break;
76  ss << "lifetime[" << toString(this->lifetimeKind) << "]=("
77  << this->tokvalue->expressionString() << ")";
78  break;
80  ss << "symbolic=(" << this->tokvalue->expressionString();
81  if (this->intvalue > 0)
82  ss << "+" << this->intvalue;
83  else if (this->intvalue < 0)
84  ss << "-" << -this->intvalue;
85  ss << ")";
86  break;
87  }
88  if (this->indirect > 0)
89  for (int i = 0; i < this->indirect; i++)
90  ss << "*";
91  if (this->path > 0)
92  ss << "@" << this->path;
93  return ss.str();
94  }
95 
96  std::string Value::infoString() const {
97  switch (valueType) {
98  case ValueType::INT:
99  return std::to_string(intvalue);
100  case ValueType::TOK:
101  return tokvalue->str();
102  case ValueType::FLOAT:
104  case ValueType::MOVED:
105  return "<Moved>";
106  case ValueType::UNINIT:
107  return "<Uninit>";
110  return "size=" + std::to_string(intvalue);
112  return "start=" + std::to_string(intvalue);
114  return "end=" + std::to_string(intvalue);
115  case ValueType::LIFETIME:
116  return "lifetime=" + tokvalue->str();
117  case ValueType::SYMBOLIC:
118  {
119  std::string result = "symbolic=" + tokvalue->expressionString();
120  if (intvalue > 0)
121  result += "+" + std::to_string(intvalue);
122  else if (intvalue < 0)
123  result += "-" + std::to_string(-intvalue);
124  return result;
125  }
126  }
127  throw InternalError(nullptr, "Invalid ValueFlow Value type");
128  }
129 
130  const char *Value::toString(MoveKind moveKind) {
131  switch (moveKind) {
133  return "NonMovedVariable";
135  return "MovedVariable";
137  return "ForwardedVariable";
138  }
139  return "";
140  }
141 
142  const char *Value::toString(LifetimeKind lifetimeKind) {
143  switch (lifetimeKind) {
145  return "Object";
147  return "SubObject";
149  return "Lambda";
151  return "Iterator";
153  return "Address";
154  }
155  return "";
156  }
157 
158  bool Value::sameToken(const Token *tok1, const Token *tok2) {
159  if (tok1 == tok2)
160  return true;
161  if (!tok1)
162  return false;
163  if (tok1->exprId() == 0 || tok2->exprId() == 0)
164  return false;
165  return tok1->exprId() == tok2->exprId();
166  }
167 
168  const char *Value::toString(LifetimeScope lifetimeScope) {
169  switch (lifetimeScope) {
171  return "Local";
173  return "Argument";
175  return "SubFunction";
177  return "ThisPointer";
179  return "ThisValue";
180  }
181  return "";
182  }
183 
184  const char *Value::toString(Bound bound) {
185  switch (bound) {
186  case Bound::Point:
187  return "Point";
188  case Bound::Upper:
189  return "Upper";
190  case Bound::Lower:
191  return "Lower";
192  }
193  return "";
194  }
195 }
static std::string toString(T value)=delete
The token list that the TokenList generates is a linked-list of this class.
Definition: token.h:150
void str(T &&s)
Definition: token.h:179
nonneg int exprId() const
Definition: token.h:883
std::string expressionString() const
Definition: token.cpp:1681
Bound bound
The value bound
Definition: vfvalue.h:265
std::string toString() const
Definition: vfvalue.cpp:41
enum ValueFlow::Value::ValueType valueType
MathLib::bigint path
Path id.
Definition: vfvalue.h:307
std::string infoString() const
Definition: vfvalue.cpp:96
ErrorPath errorPath
Definition: vfvalue.h:282
static bool sameToken(const Token *tok1, const Token *tok2)
Definition: vfvalue.cpp:158
bool isImpossible() const
Definition: vfvalue.h:365
double floatValue
float value
Definition: vfvalue.h:274
const Token * condition
Condition that this value depends on.
Definition: vfvalue.h:280
const Token * tokvalue
token value - the token that has the value.
Definition: vfvalue.h:271
long long intvalue
int value (or sometimes bool value?)
Definition: vfvalue.h:268
Value(long long val=0, Bound b=Bound::Point)
Definition: vfvalue.h:46
enum ValueFlow::Value::LifetimeKind lifetimeKind
enum ValueFlow::Value::MoveKind moveKind
void assumeCondition(const Token *tok)
Definition: vfvalue.cpp:36
enum ValueFlow::Value::LifetimeScope lifetimeScope
MoveKind
kind of moved
Definition: vfvalue.h:304
Simple container to be thrown when internal error is detected.
Definition: errortypes.h:36