@@ -452,17 +452,54 @@ static void valueFlowAfterAssign(TokenList *tokenlist, ErrorLogger *errorLogger,
452452 const Variable *var = tok->astOperand1 ()->variable ();
453453 if (!var || !var->isLocal ())
454454 continue ;
455+ const Token * endToken = 0 ;
456+ for (const Token *tok2 = var->typeStartToken (); tok2; tok2 = tok2->previous ()) {
457+ if (tok2->str () == " {" ) {
458+ endToken = tok2->link ();
459+ break ;
460+ }
461+ }
455462
456463 // Lhs values..
457464 if (!tok->astOperand2 () || tok->astOperand2 ()->values .empty ())
458465 continue ;
459466 std::list<ValueFlow::Value> values = tok->astOperand2 ()->values ;
460467
461- for (Token *tok2 = tok; tok2; tok2 = tok2-> next ()) {
462- if ( Token::Match (tok2, " [{}] " ))
463- break ;
468+ unsigned int number_of_if = 0 ;
469+
470+ for (Token *tok2 = tok; tok2 && tok2 != endToken; tok2 = tok2-> next ()) {
464471 if (Token::Match (tok2, " sizeof|typeof|typeid (" ))
465472 tok2 = tok2->linkAt (1 );
473+
474+ // conditional block of code that assigns variable..
475+ if (Token::Match (tok2, " %var% (" ) && Token::Match (tok2->linkAt (1 ), " ) {" )) {
476+ Token * const start = tok2->linkAt (1 )->next ();
477+ Token * const end = start->link ();
478+ // TODO: don't check noreturn scopes
479+ if (number_of_if > 0U && Token::findmatch (start, " %varid%" , end, varid)) {
480+ if (settings->debugwarnings )
481+ bailout (tokenlist, errorLogger, tok2, " variable " + var->nameToken ()->str () + " is assigned in conditional code" );
482+ break ;
483+ }
484+ if (Token::findmatch (start, " ++|--| %varid% ++|--|=" , end, varid)) {
485+ if (number_of_if == 0 &&
486+ Token::simpleMatch (tok2, " if (" ) &&
487+ !(Token::simpleMatch (end, " } else {" ) &&
488+ (Token::findmatch (end, " %varid%" , end->linkAt (2 ), varid) ||
489+ Token::findmatch (end, " return|continue|break" , end->linkAt (2 ))))) {
490+ ++number_of_if;
491+ tok2 = end;
492+ } else {
493+ if (settings->debugwarnings )
494+ bailout (tokenlist, errorLogger, tok2, " variable " + var->nameToken ()->str () + " is assigned in conditional code" );
495+ break ;
496+ }
497+ }
498+ }
499+
500+ else if (tok2->str () == " }" )
501+ ++number_of_if;
502+
466503 if (tok2->varId () == varid) {
467504 // bailout: assignment
468505 if (Token::Match (tok2->previous (), " !!* %var% =" )) {
@@ -471,6 +508,16 @@ static void valueFlowAfterAssign(TokenList *tokenlist, ErrorLogger *errorLogger,
471508 break ;
472509 }
473510
511+ // skip if variable is conditionally used in ?: expression
512+ if (const Token *parent = skipValueInConditionalExpression (tok2)) {
513+ if (settings->debugwarnings )
514+ bailout (tokenlist,
515+ errorLogger,
516+ tok2,
517+ " no simplification of " + tok2->str () + " within " + (Token::Match (parent," [?:]" ) ? " ?:" : parent->str ()) + " expression" );
518+ continue ;
519+ }
520+
474521 {
475522 std::list<ValueFlow::Value>::const_iterator it;
476523 for (it = values.begin (); it != values.end (); ++it)
0 commit comments