@@ -298,10 +298,6 @@ void CheckStl::mismatchingContainers()
298298
299299void CheckStl::stlOutOfBounds ()
300300{
301- // THIS ARRAY MUST BE ORDERED ALPHABETICALLY
302- static const char * const stl_bounded_container [] = {
303- " array" , " basic_string" , " deque" , " string" , " vector" , " wstring"
304- };
305301 const SymbolDatabase* const symbolDatabase = _tokenizer->getSymbolDatabase ();
306302
307303 // Scan through all scopes..
@@ -317,38 +313,50 @@ void CheckStl::stlOutOfBounds()
317313 tok = tok->linkAt (1 )->tokAt (2 );
318314 } else
319315 tok = tok->next ();
316+ tok = tok->next ();
320317
321318 // check if the for loop condition is wrong
322- if (Token::Match (tok, " ;|( %var% <= %var% . size|length ( ) ;|)|%oror%" )) {
319+ if (Token::Match (tok, " %var% <= %var% . %var% ( ) ;|)|%oror%" )) {
323320 // Is it a vector?
324- const Variable *container = tok->tokAt (3 )->variable ();
321+ const Variable *var = tok->tokAt (2 )->variable ();
322+ if (!var)
323+ continue ;
324+
325+ const Library::Container* container = _settings->library .detectContainer (var->typeStartToken ());
325326 if (!container)
326327 continue ;
327- if (!container->isStlType (stl_bounded_container))
328+
329+ Library::Container::Yield yield = container->getYield (tok->strAt (4 ));
330+ if (yield != Library::Container::SIZE)
328331 continue ;
329332
330333 // variable id for loop variable.
331- const unsigned int numId = tok->next ()-> varId ();
334+ const unsigned int numId = tok->varId ();
332335
333336 // variable id for the container variable
334- const unsigned int declarationId = container ->declarationId ();
337+ const unsigned int declarationId = var ->declarationId ();
335338
336339 for (const Token *tok3 = i->classStart ; tok3 && tok3 != i->classEnd ; tok3 = tok3->next ()) {
337340 if (tok3->varId () == declarationId) {
338- if (Token::Match (tok3->next (), " . size|length ( )" ))
339- break ;
340- else if (Token::Match (tok3->next (), " [ %varid% ]" , numId))
341- stlOutOfBoundsError (tok3, tok3->strAt (2 ), tok3->str (), false );
342- else if (Token::Match (tok3->next (), " . at ( %varid% )" , numId))
343- stlOutOfBoundsError (tok3, tok3->strAt (4 ), tok3->str (), true );
341+ tok3 = tok3->next ();
342+ if (Token::Match (tok3, " . %var% ( )" )) {
343+ Library::Container::Yield yield = container->getYield (tok3->strAt (1 ));
344+ if (yield == Library::Container::SIZE)
345+ break ;
346+ } else if (container->arrayLike_indexOp && Token::Match (tok3, " [ %varid% ]" , numId))
347+ stlOutOfBoundsError (tok3, tok3->strAt (1 ), var->name (), false );
348+ else if (Token::Match (tok3, " . %var% ( %varid% )" , numId)) {
349+ Library::Container::Yield yield = container->getYield (tok3->strAt (1 ));
350+ if (yield == Library::Container::AT_INDEX)
351+ stlOutOfBoundsError (tok3, tok3->strAt (3 ), var->name (), true );
352+ }
344353 }
345354 }
346- break ;
355+ continue ;
347356 }
348357 }
349358}
350359
351- // Error message for bad iterator usage..
352360void CheckStl::stlOutOfBoundsError (const Token *tok, const std::string &num, const std::string &var, bool at)
353361{
354362 if (at)
0 commit comments