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

Method stlOutOfBounds

lib/checkstl.cpp:1267–1351  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1265}
1266
1267void CheckStlImpl::stlOutOfBounds()
1268{
1269 logChecker("CheckStl::stlOutOfBounds");
1270
1271 const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase();
1272
1273 // Scan through all scopes..
1274 for (const Scope &scope : symbolDatabase->scopeList) {
1275 const Token* tok = scope.classDef;
1276 // only interested in conditions
1277 if ((!scope.isLoopScope() && scope.type != ScopeType::eIf) || !tok)
1278 continue;
1279
1280 const Token *condition = nullptr;
1281 if (scope.type == ScopeType::eFor) {
1282 if (Token::simpleMatch(tok->next()->astOperand2(), ";") && Token::simpleMatch(tok->next()->astOperand2()->astOperand2(), ";"))
1283 condition = tok->next()->astOperand2()->astOperand2()->astOperand1();
1284 } else if (Token::simpleMatch(tok, "do {") && Token::simpleMatch(tok->linkAt(1), "} while ("))
1285 condition = tok->linkAt(1)->tokAt(2)->astOperand2();
1286 else
1287 condition = tok->next()->astOperand2();
1288
1289 if (!condition)
1290 continue;
1291
1292 std::vector<const Token *> conds;
1293
1294 visitAstNodes(condition,
1295 [&](const Token *cond) {
1296 if (Token::Match(cond, "%oror%|&&"))
1297 return ChildrenToVisit::op1_and_op2;
1298 if (cond->isComparisonOp())
1299 conds.emplace_back(cond);
1300 return ChildrenToVisit::none;
1301 });
1302
1303 for (const Token *cond : conds) {
1304 const Token *vartok;
1305 const Token *containerToken;
1306 // check in the ast that cond is of the form "%var% <= %var% . %name% ( )"
1307 if (cond->str() == "<=" && Token::Match(cond->astOperand1(), "%var%") &&
1308 cond->astOperand2()->str() == "(" && cond->astOperand2()->astOperand1()->str() == "." &&
1309 Token::Match(cond->astOperand2()->astOperand1()->astOperand1(), "%var%") &&
1310 Token::Match(cond->astOperand2()->astOperand1()->astOperand2(), "%name%")) {
1311 vartok = cond->astOperand1();
1312 containerToken = cond->next();
1313 } else {
1314 continue;
1315 }
1316
1317 if (containerToken->hasKnownValue(ValueFlow::Value::ValueType::CONTAINER_SIZE))
1318 continue;
1319
1320 // Is it a array like container?
1321 const Library::Container* container = containerToken->valueType() ? containerToken->valueType()->container : nullptr;
1322 if (!container)
1323 continue;
1324 if (container->getYield(containerToken->strAt(2)) != Library::Container::Yield::SIZE)

Callers 1

runChecksMethod · 0.80

Calls 10

visitAstNodesFunction · 0.85
astOperand2Method · 0.80
nextMethod · 0.80
astOperand1Method · 0.80
linkAtMethod · 0.80
hasKnownValueMethod · 0.80
getYieldMethod · 0.80
simpleMatchFunction · 0.70
tokAtMethod · 0.45
strMethod · 0.45

Tested by

no test coverage detected