1717 */
1818
1919#include " valueflow.h"
20- #include " token .h"
20+ #include " errorlogger .h"
2121#include " mathlib.h"
22+ #include " settings.h"
23+ #include " symboldatabase.h"
24+ #include " token.h"
25+ #include " tokenlist.h"
2226
23- static void valueFlowBeforeCondition (Token *tokens )
27+ static void valueFlowBeforeCondition (TokenList *tokenlist, ErrorLogger *errorLogger, const Settings *settings )
2428{
25- for (Token *tok = tokens ; tok; tok = tok->next ()) {
29+ for (Token *tok = tokenlist-> front () ; tok; tok = tok->next ()) {
2630 unsigned int varid;
2731 MathLib::bigint num;
32+ const Variable *var;
2833 if (Token::Match (tok, " ==|!=|>=|<=" ) && tok->astOperand1 () && tok->astOperand2 ()) {
2934 if (tok->astOperand1 ()->isName () && tok->astOperand2 ()->isNumber ()) {
3035 varid = tok->astOperand1 ()->varId ();
36+ var = tok->astOperand1 ()->variable ();
3137 num = MathLib::toLongNumber (tok->astOperand2 ()->str ());
3238 } else if (tok->astOperand1 ()->isNumber () && tok->astOperand2 ()->isName ()) {
3339 varid = tok->astOperand2 ()->varId ();
40+ var = tok->astOperand2 ()->variable ();
3441 num = MathLib::toLongNumber (tok->astOperand1 ()->str ());
3542 } else {
3643 continue ;
3744 }
3845 } else if (Token::Match (tok->previous (), " if|while ( %var% %oror%|&&|)" ) ||
3946 Token::Match (tok, " %oror%|&& %var% %oror%|&&|)" )) {
4047 varid = tok->next ()->varId ();
48+ var = tok->next ()->variable ();
4149 num = 0 ;
4250 } else if (tok->str () == " !" && tok->astOperand1 () && tok->astOperand1 ()->isName ()) {
4351 varid = tok->astOperand1 ()->varId ();
52+ var = tok->astOperand1 ()->variable ();
4453 num = 0 ;
4554 } else {
4655 continue ;
@@ -50,26 +59,33 @@ static void valueFlowBeforeCondition(Token *tokens)
5059 continue ;
5160
5261 struct ValueFlow ::Value val;
53- val.link = tok;
62+ val.condition = tok;
5463 val.intvalue = num;
5564
56- for (Token *tok2 = tok->previous (); tok2; tok2 = tok2->previous ()) {
57- if (tok2->varId () == varid)
65+ for (Token *tok2 = tok->previous (); ; tok2 = tok2->previous ()) {
66+ if (!tok2) {
67+ if (settings->debugwarnings ) {
68+ std::list<ErrorLogger::ErrorMessage::FileLocation> callstack;
69+ callstack.push_back (ErrorLogger::ErrorMessage::FileLocation (tok,tokenlist));
70+ ErrorLogger::ErrorMessage errmsg (callstack, Severity::debug, " iterated too far" , " debugValueFlowBeforeCondition" , false );
71+ errorLogger->reportErr (errmsg);
72+ }
73+ break ;
74+ }
75+
76+ if (tok2->varId () == varid) {
5877 tok2->values .push_back (val);
59- if (tok2->str () == " {" ) {
60- if (!Token::simpleMatch (tok2->previous (), " ) {" ))
61- break ;
62- if (!Token::simpleMatch (tok2->previous ()->link ()->previous (), " if (" ))
78+ if (var && tok2 == var->nameToken ())
6379 break ;
6480 }
6581 }
6682 }
6783}
6884
69- void ValueFlow::setValues (Token *tokens )
85+ void ValueFlow::setValues (TokenList *tokenlist, ErrorLogger *errorLogger, const Settings *settings )
7086{
71- for (Token *tok = tokens ; tok; tok = tok->next ())
87+ for (Token *tok = tokenlist-> front () ; tok; tok = tok->next ())
7288 tok->values .clear ();
7389
74- valueFlowBeforeCondition (tokens );
90+ valueFlowBeforeCondition (tokenlist, errorLogger, settings );
7591}
0 commit comments