@@ -1512,6 +1512,31 @@ namespace {
15121512 return unknown ();
15131513 }
15141514
1515+ // Get the size of the container. If the container itself is not tracked in the program
1516+ // memory then check if it is symbolically equal to a container whose size is tracked.
1517+ ValueFlow::Value executeContainerSize (const Token* containerTok)
1518+ {
1519+ ValueFlow::Value v = execute (containerTok);
1520+ if (v.isContainerSizeValue ())
1521+ return v;
1522+ for (const ValueFlow::Value& value : containerTok->values ()) {
1523+ if (!value.isSymbolicValue ())
1524+ continue ;
1525+ if (value.isImpossible ())
1526+ continue ;
1527+ if (value.intvalue != 0 )
1528+ continue ;
1529+ if (!value.tokvalue )
1530+ continue ;
1531+ if (value.tokvalue ->exprId () == 0 )
1532+ continue ;
1533+ const ValueFlow::Value* sizeValue = pm->getValue (value.tokvalue ->exprId ());
1534+ if (sizeValue && sizeValue->isContainerSizeValue ())
1535+ return *sizeValue;
1536+ }
1537+ return unknown ();
1538+ }
1539+
15151540 ValueFlow::Value executeImpl (const Token* expr)
15161541 {
15171542 const ValueFlow::Value* value = nullptr ;
@@ -1540,14 +1565,14 @@ namespace {
15401565 const Token* containerTok = expr->tokAt (-2 )->astOperand1 ();
15411566 const Library::Container::Yield yield = containerTok->valueType ()->container ->getYield (expr->strAt (-1 ));
15421567 if (yield == Library::Container::Yield::SIZE ) {
1543- ValueFlow::Value v = execute (containerTok);
1568+ ValueFlow::Value v = executeContainerSize (containerTok);
15441569 if (!v.isContainerSizeValue ())
15451570 return unknown ();
15461571 v.valueType = ValueFlow::Value::ValueType::INT ;
15471572 return v;
15481573 }
15491574 if (yield == Library::Container::Yield::EMPTY ) {
1550- ValueFlow::Value v = execute (containerTok);
1575+ ValueFlow::Value v = executeContainerSize (containerTok);
15511576 if (!v.isContainerSizeValue ())
15521577 return unknown ();
15531578 if (v.isImpossible () && v.intvalue == 0 )
0 commit comments