| 5164 | }; |
| 5165 | |
| 5166 | static bool valueFlowForLoop2(const Token *tok, |
| 5167 | ProgramMemory &memory1, |
| 5168 | ProgramMemory &memory2, |
| 5169 | ProgramMemory &memoryAfter, |
| 5170 | const Settings& settings) |
| 5171 | { |
| 5172 | // for ( firstExpression ; secondExpression ; thirdExpression ) |
| 5173 | const Token *firstExpression = tok->next()->astOperand2()->astOperand1(); |
| 5174 | const Token *secondExpression = tok->next()->astOperand2()->astOperand2()->astOperand1(); |
| 5175 | const Token *thirdExpression = tok->next()->astOperand2()->astOperand2()->astOperand2(); |
| 5176 | |
| 5177 | ProgramMemory programMemory; |
| 5178 | MathLib::bigint result(0); |
| 5179 | bool error = false; |
| 5180 | execute(firstExpression, programMemory, &result, &error, settings); |
| 5181 | if (error) |
| 5182 | return false; |
| 5183 | execute(secondExpression, programMemory, &result, &error, settings); |
| 5184 | if (result == 0) { |
| 5185 | if (!error) { // 2nd expression is false => no looping |
| 5186 | ProgramMemory startMemory(programMemory); |
| 5187 | ProgramMemory endMemory(programMemory); |
| 5188 | |
| 5189 | memory1.swap(startMemory); |
| 5190 | memory2.swap(endMemory); |
| 5191 | memoryAfter.swap(programMemory); |
| 5192 | return true; |
| 5193 | } |
| 5194 | return false; |
| 5195 | } |
| 5196 | if (error) { |
| 5197 | // If a variable is reassigned in second expression, return false |
| 5198 | bool reassign = false; |
| 5199 | visitAstNodes(secondExpression, |
| 5200 | [&](const Token *t) { |
| 5201 | if (t->str() == "=" && t->astOperand1() && programMemory.hasValue(t->astOperand1()->varId())) |
| 5202 | // TODO: investigate what variable is assigned. |
| 5203 | reassign = true; |
| 5204 | return reassign ? ChildrenToVisit::done : ChildrenToVisit::op1_and_op2; |
| 5205 | }); |
| 5206 | if (reassign) |
| 5207 | return false; |
| 5208 | } |
| 5209 | |
| 5210 | ProgramMemory startMemory(programMemory); |
| 5211 | ProgramMemory endMemory; |
| 5212 | |
| 5213 | int maxcount = settings.vfOptions.maxForLoopCount; |
| 5214 | while (result != 0 && !error && --maxcount > 0) { |
| 5215 | endMemory = programMemory; |
| 5216 | execute(thirdExpression, programMemory, &result, &error, settings); |
| 5217 | if (!error) |
| 5218 | execute(secondExpression, programMemory, &result, &error, settings); |
| 5219 | } |
| 5220 | // TODO: add bailout message |
| 5221 | |
| 5222 | memory1.swap(startMemory); |
| 5223 | if (!error) { |
no test coverage detected