MCPcopy Create free account
hub / github.com/cppcheck-opensource/cppcheck / getContainerSizeFromConstructorArgs

Function getContainerSizeFromConstructorArgs

lib/valueflow.cpp:6503–6551  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

6501}
6502
6503static std::vector<ValueFlow::Value> getContainerSizeFromConstructorArgs(const std::vector<const Token*>& args,
6504 const Library::Container* container,
6505 bool known)
6506{
6507 if (astIsIntegral(args[0], false)) { // { count, i } or { count }
6508 if (args.size() == 1 || (args.size() > 1 && !astIsIntegral(args[1], false)))
6509 return {makeContainerSizeValue(args[0], known)};
6510 } else if (astIsContainer(args[0]) && args.size() == 1) { // copy constructor
6511 return getContainerValues(args[0]);
6512 } else if (isIteratorPair(args)) {
6513 std::vector<ValueFlow::Value> result = getContainerValues(args[0]);
6514 if (!result.empty())
6515 return result;
6516 // (ptr, ptr + size)
6517 if (astIsPointer(args[0]) && args[0]->exprId() != 0) {
6518 // (ptr, ptr) is empty
6519 // TODO: Use lifetime values to check if it points to the same address
6520 if (args[0]->exprId() == args[1]->exprId())
6521 return {makeContainerSizeValue(MathLib::bigint{0}, known)};
6522 // TODO: Insert iterator positions for pointers
6523 if (Token::simpleMatch(args[1], "+")) {
6524 nonneg int const eid = args[0]->exprId();
6525 const Token* vartok = args[1]->astOperand1();
6526 const Token* sizetok = args[1]->astOperand2();
6527 if (sizetok->exprId() == eid)
6528 std::swap(vartok, sizetok);
6529 if (vartok->exprId() == eid && sizetok->hasKnownIntValue())
6530 return {makeContainerSizeValue(sizetok, known)};
6531 }
6532 }
6533 } else if (container->stdStringLike) {
6534 if (astIsPointer(args[0])) {
6535 if (args.size() == 1 && args[0]->tokType() == Token::Type::eString)
6536 return {makeContainerSizeValue(Token::getStrLength(args[0]), known)};
6537 if (args.size() == 1 && args[0]->variable() && args[0]->variable()->isArray() &&
6538 args[0]->variable()->isConst() && args[0]->variable()->dimensions().size() == 1 && args[0]->variable()->dimensions()[0].known)
6539 return {makeContainerSizeValue(args[0]->variable()->dimensions()[0].num, known)};
6540 if (args.size() == 2 && astIsIntegral(args[1], false)) // { char*, count }
6541 return {makeContainerSizeValue(args[1], known)};
6542 } else if (astIsContainer(args[0])) {
6543 if (args.size() == 1) // copy constructor { str }
6544 return getContainerValues(args[0]);
6545 if (args.size() == 3) // { str, pos, count }
6546 return {makeContainerSizeValue(args[2], known)};
6547 // TODO: { str, pos }, { ..., alloc }
6548 }
6549 }
6550 return {};
6551}
6552
6553static bool valueFlowIsSameContainerType(const ValueType& contType, const Token* tok, bool isView, const Settings& settings)
6554{

Callers 2

getInitListSizeFunction · 0.85

Calls 15

astIsIntegralFunction · 0.85
makeContainerSizeValueFunction · 0.85
astIsContainerFunction · 0.85
getContainerValuesFunction · 0.85
isIteratorPairFunction · 0.85
astIsPointerFunction · 0.85
astOperand1Method · 0.80
astOperand2Method · 0.80
variableMethod · 0.80
isArrayMethod · 0.80
isConstMethod · 0.80
simpleMatchFunction · 0.70

Tested by

no test coverage detected