Skip to content

Commit 7ece58c

Browse files
committed
CheckStl::stlOutOfBounds() now uses <container> information from Libraries
1 parent e39729f commit 7ece58c

File tree

2 files changed

+29
-18
lines changed

2 files changed

+29
-18
lines changed

lib/checkstl.cpp

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -298,10 +298,6 @@ void CheckStl::mismatchingContainers()
298298

299299
void 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..
352360
void CheckStl::stlOutOfBoundsError(const Token *tok, const std::string &num, const std::string &var, bool at)
353361
{
354362
if (at)

test/teststl.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@ class TestStl : public TestFixture {
3131
}
3232

3333
private:
34+
Settings settings;
35+
3436
void run() {
37+
LOAD_LIB_2(settings.library, "std.cfg");
38+
3539
TEST_CASE(iterator1);
3640
TEST_CASE(iterator2);
3741
TEST_CASE(iterator3);
@@ -134,7 +138,6 @@ class TestStl : public TestFixture {
134138
// Clear the error buffer..
135139
errout.str("");
136140

137-
Settings settings;
138141
settings.addEnabled("warning");
139142
settings.addEnabled("style");
140143
settings.addEnabled("performance");

0 commit comments

Comments
 (0)