@@ -2936,38 +2936,43 @@ static Analyzer::Result valueFlowForwardExpression(Token* startToken,
29362936 return result;
29372937}
29382938
2939- static const Token* parseBinaryIntOp (const Token* expr, MathLib::bigint& known)
2939+ static const Token* parseBinaryIntOp (const Token* expr,
2940+ const std::function<std::vector<MathLib::bigint>(const Token*)>& eval,
2941+ MathLib::bigint& known)
29402942{
29412943 if (!expr)
29422944 return nullptr ;
29432945 if (!expr->astOperand1 () || !expr->astOperand2 ())
29442946 return nullptr ;
2945- if (expr->astOperand1 ()->exprId () == 0 && ! expr->astOperand1 ()->hasKnownIntValue () )
2947+ if (expr->astOperand1 ()->exprId () == 0 && expr->astOperand2 ()->exprId () == 0 )
29462948 return nullptr ;
2947- if (expr->astOperand2 ()->exprId () == 0 && !expr->astOperand2 ()->hasKnownIntValue ())
2949+ std::vector<MathLib::bigint> x1 = eval (expr->astOperand1 ());
2950+ std::vector<MathLib::bigint> x2 = eval (expr->astOperand2 ());
2951+ if (expr->astOperand1 ()->exprId () == 0 && x1.empty ())
2952+ return nullptr ;
2953+ if (expr->astOperand2 ()->exprId () == 0 && x2.empty ())
29482954 return nullptr ;
2949- const Token* knownTok = nullptr ;
29502955 const Token* varTok = nullptr ;
2951- if (expr-> astOperand1 ()-> hasKnownIntValue () && !expr-> astOperand2 ()-> hasKnownIntValue ()) {
2956+ if (!x1. empty () && x2. empty ()) {
29522957 varTok = expr->astOperand2 ();
2953- knownTok = expr-> astOperand1 ();
2954- } else if (expr-> astOperand2 ()-> hasKnownIntValue () && !expr-> astOperand1 ()-> hasKnownIntValue ()) {
2958+ known = x1. front ();
2959+ } else if (x1. empty () && !x2. empty ()) {
29552960 varTok = expr->astOperand1 ();
2956- knownTok = expr-> astOperand2 ();
2961+ known = x2. front ();
29572962 }
2958- if (knownTok)
2959- known = knownTok->values ().front ().intvalue ;
29602963 return varTok;
29612964}
29622965
2963- static const Token* solveExprValue (const Token* expr, ValueFlow::Value& value)
2966+ const Token* solveExprValue (const Token* expr,
2967+ const std::function<std::vector<MathLib::bigint>(const Token*)>& eval,
2968+ ValueFlow::Value& value)
29642969{
29652970 if (!value.isIntValue () && !value.isIteratorValue () && !value.isSymbolicValue ())
29662971 return expr;
29672972 if (value.isSymbolicValue () && !Token::Match (expr, " +|-" ))
29682973 return expr;
29692974 MathLib::bigint intval;
2970- const Token* binaryTok = parseBinaryIntOp (expr, intval);
2975+ const Token* binaryTok = parseBinaryIntOp (expr, eval, intval);
29712976 bool rhs = astIsRHS (binaryTok);
29722977 // If its on the rhs, then -1 multiplication is needed, which is not possible with simple delta analysis used currently for symbolic values
29732978 if (value.isSymbolicValue () && rhs && Token::simpleMatch (expr, " -" ))
@@ -2976,30 +2981,42 @@ static const Token* solveExprValue(const Token* expr, ValueFlow::Value& value)
29762981 switch (expr->str ()[0 ]) {
29772982 case ' +' : {
29782983 value.intvalue -= intval;
2979- return solveExprValue (binaryTok, value);
2984+ return solveExprValue (binaryTok, eval, value);
29802985 }
29812986 case ' -' : {
29822987 if (rhs)
29832988 value.intvalue = intval - value.intvalue ;
29842989 else
29852990 value.intvalue += intval;
2986- return solveExprValue (binaryTok, value);
2991+ return solveExprValue (binaryTok, eval, value);
29872992 }
29882993 case ' *' : {
29892994 if (intval == 0 )
29902995 break ;
29912996 value.intvalue /= intval;
2992- return solveExprValue (binaryTok, value);
2997+ return solveExprValue (binaryTok, eval, value);
29932998 }
29942999 case ' ^' : {
29953000 value.intvalue ^= intval;
2996- return solveExprValue (binaryTok, value);
3001+ return solveExprValue (binaryTok, eval, value);
29973002 }
29983003 }
29993004 }
30003005 return expr;
30013006}
30023007
3008+ static const Token* solveExprValue (const Token* expr, ValueFlow::Value& value)
3009+ {
3010+ return solveExprValue (
3011+ expr,
3012+ [](const Token* tok) -> std::vector<MathLib::bigint> {
3013+ if (tok->hasKnownIntValue ())
3014+ return {tok->values ().front ().intvalue };
3015+ return {};
3016+ },
3017+ value);
3018+ }
3019+
30033020ValuePtr<Analyzer> makeAnalyzer (const Token* exprTok, ValueFlow::Value value, const TokenList* tokenlist)
30043021{
30053022 const Token* expr = solveExprValue (exprTok, value);
0 commit comments