Skip to content

Commit 5636497

Browse files
committed
Fixed #8863 (false positive: (warning) Accessing an item in container 's'. Either the condition 's.empty()' is redundant or 's' can be empty.)
1 parent dd62da0 commit 5636497

File tree

2 files changed

+28
-7
lines changed

2 files changed

+28
-7
lines changed

lib/valueflow.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,19 @@ static void combineValueProperties(const ValueFlow::Value &value1, const ValueFl
376376
result->errorPath = (value1.errorPath.empty() ? value2 : value1).errorPath;
377377
}
378378

379+
380+
static const Token *getCastTypeStartToken(const Token *parent)
381+
{
382+
// TODO: This might be a generic utility function?
383+
if (!parent || parent->str() != "(")
384+
return nullptr;
385+
if (!parent->astOperand2() && Token::Match(parent,"( %name%"))
386+
return parent->next();
387+
if (parent->astOperand2() && Token::Match(parent->astOperand1(), "const_cast|dynamic_cast|reinterpret_cast|static_cast <"))
388+
return parent->astOperand1()->tokAt(2);
389+
return nullptr;
390+
}
391+
379392
/** Set token value for cast */
380393
static void setTokenValueCast(Token *parent, const ValueType &valueType, const ValueFlow::Value &value, const Settings *settings);
381394

@@ -446,13 +459,8 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
446459
}
447460

448461
// cast..
449-
if (parent->str() == "(" && !parent->astOperand2() && Token::Match(parent,"( %name%")) {
450-
const ValueType &valueType = ValueType::parseDecl(parent->next(), settings);
451-
setTokenValueCast(parent, valueType, value, settings);
452-
}
453-
454-
else if (parent->str() == "(" && parent->astOperand2() && Token::Match(parent->astOperand1(), "const_cast|dynamic_cast|reinterpret_cast|static_cast <")) {
455-
const ValueType &valueType = ValueType::parseDecl(parent->astOperand1()->tokAt(2), settings);
462+
if (const Token *castType = getCastTypeStartToken(parent)) {
463+
const ValueType &valueType = ValueType::parseDecl(castType, settings);
456464
setTokenValueCast(parent, valueType, value, settings);
457465
}
458466

@@ -4644,6 +4652,12 @@ static void valueFlowContainerAfterCondition(TokenList *tokenlist,
46444652
// TODO: Handle .size()
46454653
if (!isContainerEmpty(vartok))
46464654
return cond;
4655+
const Token *parent = tok->astParent();
4656+
while (parent) {
4657+
if (Token::Match(parent, "%comp%|!"))
4658+
return cond;
4659+
parent = parent->astParent();
4660+
}
46474661
ValueFlow::Value value(tok, 0LL);
46484662
value.valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE;
46494663
cond.true_values.emplace_back(value);

test/testvalueflow.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3629,6 +3629,13 @@ class TestValueFlow : public TestFixture {
36293629

36303630
LOAD_LIB_2(settings.library, "std.cfg");
36313631

3632+
// condition
3633+
code = "void f(const std::list<int> &ints) {\n"
3634+
" if (!static_cast<bool>(ints.empty()))\n"
3635+
" ints.front();\n"
3636+
"}";
3637+
ASSERT(tokenValues(code, "ints . front").empty());
3638+
36323639
// valueFlowContainerReverse
36333640
code = "void f(const std::list<int> &ints) {\n"
36343641
" ints.front();\n" // <- container can be empty

0 commit comments

Comments
 (0)