| 4258 | } |
| 4259 | |
| 4260 | void CheckOtherImpl::checkKnownArgument() |
| 4261 | { |
| 4262 | if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("knownArgument")) |
| 4263 | return; |
| 4264 | logChecker("CheckOther::checkKnownArgument"); // style |
| 4265 | const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); |
| 4266 | for (const Scope *functionScope : symbolDatabase->functionScopes) { |
| 4267 | for (const Token *tok = functionScope->bodyStart; tok != functionScope->bodyEnd; tok = tok->next()) { |
| 4268 | if (!tok->hasKnownIntValue() || tok->isExpandedMacro()) |
| 4269 | continue; |
| 4270 | if (Token::Match(tok, "++|--|%assign%")) |
| 4271 | continue; |
| 4272 | if (!Token::Match(tok->astParent(), "(|{|,")) |
| 4273 | continue; |
| 4274 | if (tok->astParent()->isCast() || (tok->isCast() && Token::Match(tok->astOperand2(), "++|--|%assign%"))) |
| 4275 | continue; |
| 4276 | int argn = -1; |
| 4277 | const Token* ftok = getTokenArgumentFunction(tok, argn); |
| 4278 | if (!ftok) |
| 4279 | continue; |
| 4280 | if (ftok->isCast()) |
| 4281 | continue; |
| 4282 | if (Token::Match(ftok, "if|while|switch|sizeof")) |
| 4283 | continue; |
| 4284 | if (tok == tok->astParent()->previous()) |
| 4285 | continue; |
| 4286 | if (isConstVarExpression(tok)) |
| 4287 | continue; |
| 4288 | if (Token::Match(tok->astOperand1(), "%name% (")) |
| 4289 | continue; |
| 4290 | const Token * tok2 = tok; |
| 4291 | if (isCPPCast(tok2)) |
| 4292 | tok2 = tok2->astOperand2(); |
| 4293 | if (isVariableExpression(tok2)) |
| 4294 | continue; |
| 4295 | if (tok->isComparisonOp() && |
| 4296 | isSameExpression( |
| 4297 | true, tok->astOperand1(), tok->astOperand2(), mSettings, true, true)) |
| 4298 | continue; |
| 4299 | // ensure that there is a integer variable in expression with unknown value |
| 4300 | const Token* vartok = nullptr; |
| 4301 | visitAstNodes(tok, [&](const Token* child) { |
| 4302 | if (Token::Match(child, "%var%|.|[")) { |
| 4303 | if (child->hasKnownIntValue()) |
| 4304 | return ChildrenToVisit::none; |
| 4305 | if (astIsIntegral(child, false) && !astIsPointer(child) && child->values().empty()) { |
| 4306 | vartok = child; |
| 4307 | return ChildrenToVisit::done; |
| 4308 | } |
| 4309 | } |
| 4310 | return ChildrenToVisit::op1_and_op2; |
| 4311 | }); |
| 4312 | if (!vartok) |
| 4313 | continue; |
| 4314 | if (vartok->astSibling() && |
| 4315 | findAstNode(vartok->astSibling(), [](const Token* child) { |
| 4316 | return Token::simpleMatch(child, "sizeof"); |
| 4317 | })) |
no test coverage detected