| 273 | } |
| 274 | |
| 275 | virtual Action isWritable(const Token* tok, Direction d) const { |
| 276 | const ValueFlow::Value* value = getValue(tok); |
| 277 | if (!value) |
| 278 | return Action::None; |
| 279 | if (!(value->isIntValue() || value->isFloatValue() || value->isSymbolicValue() || value->isLifetimeValue())) |
| 280 | return Action::None; |
| 281 | const Token* parent = tok->astParent(); |
| 282 | // Only if its invertible |
| 283 | if (value->isImpossible() && !Token::Match(parent, "+=|-=|*=|++|--")) |
| 284 | return Action::None; |
| 285 | if (value->isLifetimeValue()) { |
| 286 | if (value->lifetimeKind != ValueFlow::Value::LifetimeKind::Iterator) |
| 287 | return Action::None; |
| 288 | if (!Token::Match(parent, "++|--|+=")) |
| 289 | return Action::None; |
| 290 | return Action::Read | Action::Write; |
| 291 | } |
| 292 | if (parent && parent->isAssignmentOp() && astIsLHS(tok)) { |
| 293 | const Token* rhs = parent->astOperand2(); |
| 294 | std::vector<MathLib::bigint> result = evaluateInt(rhs); |
| 295 | if (!result.empty()) { |
| 296 | ValueFlow::Value rhsValue{result.front()}; |
| 297 | Action a; |
| 298 | if (!evalAssignment(*value, getAssign(parent, d), rhsValue)) |
| 299 | a = Action::Invalid; |
| 300 | else |
| 301 | a = Action::Write; |
| 302 | if (parent->str() != "=") { |
| 303 | a |= Action::Read | Action::Incremental; |
| 304 | } else { |
| 305 | if (!value->isImpossible() && value->equalValue(rhsValue)) |
| 306 | a = Action::Idempotent; |
| 307 | if (tok->exprId() != 0 && |
| 308 | findAstNode(rhs, [&](const Token* child) { |
| 309 | return tok->exprId() == child->exprId(); |
| 310 | })) |
| 311 | a |= Action::Incremental; |
| 312 | } |
| 313 | return a; |
| 314 | } |
| 315 | } |
| 316 | |
| 317 | // increment/decrement |
| 318 | if (Token::Match(tok->astParent(), "++|--")) { |
| 319 | return Action::Read | Action::Write | Action::Incremental; |
| 320 | } |
| 321 | return Action::None; |
| 322 | } |
| 323 | |
| 324 | virtual void writeValue(ValueFlow::Value* value, const Token* tok, Direction d) const { |
| 325 | if (!value) |
no test coverage detected