| 6101 | int depth = 20); |
| 6102 | |
| 6103 | static bool isContainerSizeChangedByFunction(const Token* tok, |
| 6104 | int indirect, |
| 6105 | const Settings& settings, |
| 6106 | int depth = 20) |
| 6107 | { |
| 6108 | if (!tok->valueType()) |
| 6109 | return false; |
| 6110 | if (!astIsContainer(tok)) |
| 6111 | return false; |
| 6112 | // If we are accessing an element then we are not changing the container size |
| 6113 | if (Token::Match(tok, "%name% . %name% (")) { |
| 6114 | const Library::Container::Yield yield = getLibraryContainer(tok)->getYield(tok->strAt(2)); |
| 6115 | if (yield != Library::Container::Yield::NO_YIELD) |
| 6116 | return false; |
| 6117 | } |
| 6118 | if (Token::simpleMatch(tok->astParent(), "[")) |
| 6119 | return false; |
| 6120 | |
| 6121 | // address of variable |
| 6122 | const bool addressOf = tok->valueType()->pointer || (tok->astParent() && tok->astParent()->isUnaryOp("&")); |
| 6123 | |
| 6124 | int narg; |
| 6125 | const Token * ftok = getTokenArgumentFunction(tok, narg); |
| 6126 | if (!ftok) |
| 6127 | return false; // not a function => variable not changed |
| 6128 | const Function * fun = ftok->function(); |
| 6129 | if (fun && !fun->isImplicitlyVirtual()) { |
| 6130 | const Variable *arg = fun->getArgumentVar(narg); |
| 6131 | if (arg) { |
| 6132 | const bool isPointer = addressOf || indirect > 0; |
| 6133 | if (!arg->isReference() && !isPointer) |
| 6134 | return false; |
| 6135 | if (!isPointer && arg->isConst()) |
| 6136 | return false; |
| 6137 | if (arg->valueType() && arg->valueType()->constness == 1) |
| 6138 | return false; |
| 6139 | const Scope * scope = fun->functionScope; |
| 6140 | if (scope) { |
| 6141 | // Argument not used |
| 6142 | if (!arg->nameToken()) |
| 6143 | return false; |
| 6144 | if (depth > 0) |
| 6145 | return isContainerSizeChanged(arg->nameToken(), |
| 6146 | scope->bodyStart, |
| 6147 | scope->bodyEnd, |
| 6148 | addressOf ? indirect + 1 : indirect, |
| 6149 | settings, |
| 6150 | depth - 1); |
| 6151 | } |
| 6152 | // Don't know => Safe guess |
| 6153 | return true; |
| 6154 | } |
| 6155 | } |
| 6156 | |
| 6157 | bool inconclusive = false; |
| 6158 | const bool isChanged = isVariableChangedByFunctionCall(tok, indirect, settings, &inconclusive); |
| 6159 | return (isChanged || inconclusive); |
| 6160 | } |
no test coverage detected