| 553 | //--------------------------------------------------------------------------- |
| 554 | |
| 555 | ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok) const |
| 556 | { |
| 557 | if (!bufTok->valueType()) |
| 558 | return ValueFlow::Value(-1); |
| 559 | if (bufTok->isUnaryOp("&")) |
| 560 | bufTok = bufTok->astOperand1(); |
| 561 | const Variable *var = bufTok->variable(); |
| 562 | |
| 563 | if (!var || var->dimensions().empty()) { |
| 564 | const ValueFlow::Value *value = getBufferSizeValue(bufTok); |
| 565 | if (value) |
| 566 | return *value; |
| 567 | } |
| 568 | |
| 569 | if (!var || var->isPointer()) |
| 570 | return ValueFlow::Value(-1); |
| 571 | |
| 572 | const MathLib::bigint dim = std::accumulate(var->dimensions().cbegin(), var->dimensions().cend(), MathLib::bigint(1), [](MathLib::bigint i1, const Dimension &dim) { |
| 573 | return i1 * dim.num; |
| 574 | }); |
| 575 | |
| 576 | ValueFlow::Value v; |
| 577 | v.setKnown(); |
| 578 | v.valueType = ValueFlow::Value::ValueType::BUFFER_SIZE; |
| 579 | |
| 580 | if (var->isPointerArray()) |
| 581 | v.intvalue = dim * mSettings.platform.sizeof_pointer; |
| 582 | else { |
| 583 | const size_t typeSize = bufTok->valueType()->getSizeOf(mSettings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointee); |
| 584 | v.intvalue = dim * typeSize; |
| 585 | } |
| 586 | |
| 587 | return v; |
| 588 | } |
| 589 | //--------------------------------------------------------------------------- |
| 590 | |
| 591 | static bool checkBufferSize(const Token *ftok, const Library::ArgumentChecks::MinSize &minsize, const std::vector<const Token *> &args, const MathLib::bigint bufferSize, const Settings &settings, const Tokenizer* tokenizer) |
nothing calls this directly
no test coverage detected