set ValueFlow value and perform calculations if possible */
| 218 | |
| 219 | /** set ValueFlow value and perform calculations if possible */ |
| 220 | void setTokenValue(Token* tok, |
| 221 | Value value, |
| 222 | const Settings& settings, |
| 223 | SourceLocation loc) |
| 224 | { |
| 225 | // Skip setting values that are too big since its ambiguous |
| 226 | if (!value.isImpossible() && value.isIntValue() && value.intvalue < 0 && astIsUnsigned(tok) |
| 227 | && tok->valueType()->getSizeOf(settings, ValueType::Accuracy::LowerBound, ValueType::SizeOf::Pointer) |
| 228 | >= sizeof(MathLib::bigint)) |
| 229 | return; |
| 230 | |
| 231 | if (!value.isImpossible() && value.isIntValue()) |
| 232 | value = truncateImplicitConversion(tok->astParent(), value, settings); |
| 233 | |
| 234 | if (settings.debugnormal) |
| 235 | setSourceLocation(value, loc, tok); |
| 236 | |
| 237 | if (!tok->addValue(value)) |
| 238 | return; |
| 239 | |
| 240 | if (value.path < 0) |
| 241 | return; |
| 242 | |
| 243 | Token *parent = tok->astParent(); |
| 244 | if (!parent) |
| 245 | return; |
| 246 | |
| 247 | if (Token::simpleMatch(parent, ",") && !parent->isInitComma() && astIsRHS(tok)) { |
| 248 | const Token* callParent = findParent(parent, [](const Token* p) { |
| 249 | return !Token::simpleMatch(p, ","); |
| 250 | }); |
| 251 | // Ensure that the comma isn't a function call |
| 252 | if (!callParent || (!Token::Match(callParent->previous(), "%name%|> (") && !Token::simpleMatch(callParent, "{") && |
| 253 | (!Token::Match(callParent, "( %name%") || settings.library.isNotLibraryFunction(callParent->next())) && |
| 254 | !(callParent->str() == "(" && (Token::simpleMatch(callParent->astOperand1(), "*") || Token::Match(callParent->astOperand1(), "%name%|("))))) { |
| 255 | setTokenValue(parent, std::move(value), settings); |
| 256 | return; |
| 257 | } |
| 258 | } |
| 259 | |
| 260 | if (Token::simpleMatch(parent, "=") && astIsRHS(tok)) { |
| 261 | setTokenValue(parent, value, settings); |
| 262 | if (!value.isUninitValue()) |
| 263 | return; |
| 264 | } |
| 265 | |
| 266 | if (value.isContainerSizeValue() && astIsContainer(tok)) { |
| 267 | // .empty, .size, +"abc", +'a' |
| 268 | if (Token::Match(parent, "+|==|!=") && parent->astOperand1() && parent->astOperand2()) { |
| 269 | for (const Value &value1 : parent->astOperand1()->values()) { |
| 270 | if (value1.isImpossible()) |
| 271 | continue; |
| 272 | for (const Value &value2 : parent->astOperand2()->values()) { |
| 273 | if (value2.isImpossible()) |
| 274 | continue; |
| 275 | if (value1.path != value2.path) |
| 276 | continue; |
| 277 | Value result; |
no test coverage detected