Skip to content

Commit dfdfad0

Browse files
Fix #8983 FN containerOutOfBounds (passing empty init list) (#8055)
Co-authored-by: chrchr-github <[email protected]>
1 parent b66f900 commit dfdfad0

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

lib/valueflow.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6706,6 +6706,26 @@ static void valueFlowContainerSize(const TokenList& tokenlist,
67066706
}
67076707
for (const ValueFlow::Value& value : values)
67086708
setTokenValue(tok, value, settings);
6709+
}
6710+
else if (Token::Match(tok->previous(), ",|( {")) {
6711+
int nArg{};
6712+
if (const Token* funcTok = getTokenArgumentFunction(tok, nArg)) {
6713+
if (const Function* func = funcTok->function()) {
6714+
if (const Variable* var = func->getArgumentVar(nArg)) {
6715+
if (var->valueType() && var->valueType()->container && var->valueType()->container->size_templateArgNo < 0) {
6716+
std::vector<ValueFlow::Value> values = getInitListSize(tok, var->valueType(), settings, true);
6717+
ValueFlow::Value tokValue;
6718+
tokValue.valueType = ValueFlow::Value::ValueType::TOK;
6719+
tokValue.tokvalue = tok;
6720+
tokValue.setKnown();
6721+
values.push_back(std::move(tokValue));
6722+
6723+
for (const ValueFlow::Value &value : values)
6724+
setTokenValue(tok, value, settings);
6725+
}
6726+
}
6727+
}
6728+
}
67096729
} else if (Token::Match(tok, ";|{|} %var% =") && Token::Match(tok->tokAt(2)->astOperand2(), "[({]") &&
67106730
// init list
67116731
((tok->tokAt(2) == tok->tokAt(2)->astOperand2()->astParent() && !tok->tokAt(2)->astOperand2()->astOperand2() && tok->tokAt(2)->astOperand2()->str() == "{") ||

test/teststl.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,28 @@ class TestStl : public TestFixture {
945945
" (void)v[0];\n"
946946
"}\n");
947947
ASSERT_EQUALS("", errout_str());
948+
949+
checkNormal("int f(const std::vector<int>& v) {\n" // #8983
950+
" return v[2];\n"
951+
"}\n"
952+
"int g() {\n"
953+
" return f({});\n"
954+
"}\n"
955+
"int h() {\n"
956+
" return f({ 1, 2 });\n"
957+
"}\n");
958+
ASSERT_EQUALS("[test.cpp:2:13]: error: Out of bounds access in 'v[2]', if 'v' size is 2 and '2' is 2 [containerOutOfBounds]\n"
959+
"[test.cpp:2:13]: error: Out of bounds access in expression 'v[2]' because 'v' is empty. [containerOutOfBounds]\n",
960+
errout_str());
961+
962+
checkNormal("int f(int x, const std::vector<int>& v) {\n"
963+
" return x + v[0];\n"
964+
"}\n"
965+
"int g() {\n"
966+
" return f(1, {});\n"
967+
"}\n");
968+
ASSERT_EQUALS("[test.cpp:2:17]: error: Out of bounds access in expression 'v[0]' because 'v' is empty. [containerOutOfBounds]\n",
969+
errout_str());
948970
}
949971

950972
void outOfBoundsSymbolic()

0 commit comments

Comments
 (0)