@@ -508,6 +508,24 @@ static bool isComputableValue(const Token* parent, const ValueFlow::Value& value
508508 return true ;
509509}
510510
511+ static Library::Container::Yield getContainerYield (Token* tok, const Settings* settings, Token** parent = nullptr )
512+ {
513+ if (Token::Match (tok, " . %name% (" ) && tok->astParent () == tok->tokAt (2 ) && tok->astOperand1 () &&
514+ tok->astOperand1 ()->valueType ()) {
515+ const Library::Container* c = getLibraryContainer (tok->astOperand1 ());
516+ if (parent)
517+ *parent = tok->astParent ();
518+ return c ? c->getYield (tok->strAt (1 )) : Library::Container::Yield::NO_YIELD;
519+ } else if (Token::Match (tok->previous (), " %name% (" )) {
520+ if (parent)
521+ *parent = tok;
522+ if (const Library::Function* f = settings->library .getFunction (tok->previous ())) {
523+ return f->containerYield ;
524+ }
525+ }
526+ return Library::Container::Yield::NO_YIELD;
527+ }
528+
511529/* * Set token value for cast */
512530static void setTokenValueCast (Token *parent, const ValueType &valueType, const ValueFlow::Value &value, const Settings *settings);
513531
@@ -663,36 +681,25 @@ static void setTokenValue(Token* tok,
663681 }
664682 }
665683 }
666- else if ( Token::Match (parent, " . %name% ( " ) && parent-> astParent () == parent-> tokAt ( 2 ) &&
667- parent-> astOperand1 () && parent-> astOperand1 ()-> valueType ()) {
668- const Library::Container* c = getLibraryContainer (parent-> astOperand1 ());
669- const Library::Container::Yield yields = c ? c-> getYield (parent-> strAt ( 1 )) : Library::Container::Yield::NO_YIELD ;
670- if (yields == Library::Container::Yield::SIZE) {
671- ValueFlow::Value v (value );
672- v. valueType = ValueFlow::Value::ValueType::INT;
673- setTokenValue (parent-> astParent (), std::move (v), settings );
674- } else if (yields == Library::Container::Yield::EMPTY) {
675- ValueFlow::Value v (value) ;
676- v. valueType = ValueFlow::Value::ValueType::INT;
677- if (value.isImpossible () && value. intvalue == 0 )
684+ Token* next = nullptr ;
685+ const Library::Container::Yield yields = getContainerYield (parent, settings, &next);
686+ if (yields == Library::Container::Yield::SIZE) {
687+ ValueFlow::Value v (value) ;
688+ v. valueType = ValueFlow::Value::ValueType::INT;
689+ setTokenValue (next, std::move (v), settings );
690+ } else if (yields == Library::Container::Yield::EMPTY) {
691+ ValueFlow::Value v (value );
692+ v. valueType = ValueFlow::Value::ValueType::INT;
693+ v. bound = ValueFlow::Value::Bound::Point ;
694+ if (value. isImpossible ()) {
695+ if (value.intvalue == 0 )
678696 v.setKnown ();
679697 else
680- v.intvalue = !v.intvalue ;
681- setTokenValue (parent->astParent (), std::move (v), settings);
682- }
683- } else if (Token::Match (parent->previous (), " %name% (" )) {
684- if (const Library::Function* f = settings->library .getFunction (parent->previous ())) {
685- if (f->containerYield == Library::Container::Yield::SIZE) {
686- ValueFlow::Value v (value);
687- v.valueType = ValueFlow::Value::ValueType::INT;
688- setTokenValue (parent, std::move (v), settings);
689- } else if (f->containerYield == Library::Container::Yield::EMPTY) {
690- ValueFlow::Value v (value);
691- v.intvalue = !v.intvalue ;
692- v.valueType = ValueFlow::Value::ValueType::INT;
693- setTokenValue (parent, std::move (v), settings);
694- }
698+ v.setPossible ();
699+ } else {
700+ v.intvalue = !v.intvalue ;
695701 }
702+ setTokenValue (next, std::move (v), settings);
696703 }
697704 return ;
698705 }
@@ -917,7 +924,10 @@ static void setTokenValue(Token* tok,
917924 if (val.isImpossible () && val.intvalue != 0 )
918925 continue ;
919926 ValueFlow::Value v (val);
920- v.intvalue = !v.intvalue ;
927+ if (val.isImpossible ())
928+ v.setKnown ();
929+ else
930+ v.intvalue = !v.intvalue ;
921931 setTokenValue (parent, std::move (v), settings);
922932 }
923933 }
@@ -1859,7 +1869,7 @@ static void valueFlowImpossibleValues(TokenList* tokenList, const Settings* sett
18591869 ValueFlow::Value value{0 };
18601870 value.setImpossible ();
18611871 setTokenValue (tok->linkAt (1 )->next (), std::move (value), settings);
1862- } else if (tokenList->isCPP () && Token::simpleMatch (tok, " this" )) {
1872+ } else if (( tokenList->isCPP () && Token::simpleMatch (tok, " this" )) || tok-> isUnaryOp ( " & " )) {
18631873 ValueFlow::Value value{0 };
18641874 value.setImpossible ();
18651875 setTokenValue (tok, std::move (value), settings);
@@ -6666,16 +6676,7 @@ static void valueFlowInferCondition(TokenList* tokenlist,
66666676 continue ;
66676677 if (tok->hasKnownIntValue ())
66686678 continue ;
6669- if (tok->variable () && (Token::Match (tok->astParent (), " ?|&&|!|%oror%" ) ||
6670- Token::Match (tok->astParent ()->previous (), " if|while (" ))) {
6671- std::vector<ValueFlow::Value> result = infer (IntegralInferModel{}, " !=" , tok->values (), 0 );
6672- if (result.size () != 1 )
6673- continue ;
6674- ValueFlow::Value value = result.front ();
6675- value.intvalue = 1 ;
6676- value.bound = ValueFlow::Value::Bound::Point;
6677- setTokenValue (tok, std::move (value), settings);
6678- } else if (Token::Match (tok, " %comp%|-" ) && tok->astOperand1 () && tok->astOperand2 ()) {
6679+ if (Token::Match (tok, " %comp%|-" ) && tok->astOperand1 () && tok->astOperand2 ()) {
66796680 if (astIsIterator (tok->astOperand1 ()) || astIsIterator (tok->astOperand2 ())) {
66806681 static const std::array<ValuePtr<InferModel>, 2 > iteratorModels = {EndIteratorInferModel{},
66816682 StartIteratorInferModel{}};
@@ -6694,6 +6695,15 @@ static void valueFlowInferCondition(TokenList* tokenlist,
66946695 setTokenValue (tok, std::move (value), settings);
66956696 }
66966697 }
6698+ } else if (Token::Match (tok->astParent (), " ?|&&|!|%oror%" ) ||
6699+ Token::Match (tok->astParent ()->previous (), " if|while (" )) {
6700+ std::vector<ValueFlow::Value> result = infer (IntegralInferModel{}, " !=" , tok->values (), 0 );
6701+ if (result.size () != 1 )
6702+ continue ;
6703+ ValueFlow::Value value = result.front ();
6704+ value.intvalue = 1 ;
6705+ value.bound = ValueFlow::Value::Bound::Point;
6706+ setTokenValue (tok, std::move (value), settings);
66976707 }
66986708 }
66996709}
0 commit comments