MCPcopy Create free account
hub / github.com/cppcheck-opensource/cppcheck / programMemoryParseCondition

Function programMemoryParseCondition

lib/programmemory.cpp:340–399  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

338}
339
340static void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, const Token* endTok, const Settings& settings, bool then)
341{
342 auto eval = [&](const Token* t) -> std::vector<MathLib::bigint> {
343 if (!t)
344 return std::vector<MathLib::bigint>{};
345 if (const ValueFlow::Value* v = t->getKnownValue(ValueFlow::Value::ValueType::INT))
346 return {v->intvalue};
347 MathLib::bigint result = 0;
348 bool error = false;
349 execute(t, pm, &result, &error, settings);
350 if (!error)
351 return {result};
352 return std::vector<MathLib::bigint>{};
353 };
354 if (Token::Match(tok, "==|>=|<=|<|>|!=")) {
355 ValueFlow::Value truevalue;
356 ValueFlow::Value falsevalue;
357 const Token* vartok = parseCompareInt(tok, truevalue, falsevalue, eval);
358 if (!vartok)
359 return;
360 if (vartok->exprId() == 0)
361 return;
362 if (!truevalue.isIntValue())
363 return;
364 if (endTok && findExpressionChanged(vartok, tok->next(), endTok, settings))
365 return;
366 const bool impossible = (tok->str() == "==" && !then) || (tok->str() == "!=" && then);
367 const ValueFlow::Value& v = then ? truevalue : falsevalue;
368 pm.setValue(vartok, impossible ? asImpossible(v) : v);
369 const Token* containerTok = settings.library.getContainerFromYield(vartok, Library::Container::Yield::SIZE);
370 if (containerTok)
371 pm.setContainerSizeValue(containerTok, v.intvalue, !impossible);
372 } else if (Token::simpleMatch(tok, "!")) {
373 programMemoryParseCondition(pm, tok->astOperand1(), endTok, settings, !then);
374 } else if (then && Token::simpleMatch(tok, "&&")) {
375 programMemoryParseCondition(pm, tok->astOperand1(), endTok, settings, then);
376 programMemoryParseCondition(pm, tok->astOperand2(), endTok, settings, then);
377 } else if (!then && Token::simpleMatch(tok, "||")) {
378 programMemoryParseCondition(pm, tok->astOperand1(), endTok, settings, then);
379 programMemoryParseCondition(pm, tok->astOperand2(), endTok, settings, then);
380 } else if (Token::Match(tok, "&&|%oror%")) {
381 std::vector<MathLib::bigint> lhs = eval(tok->astOperand1());
382 std::vector<MathLib::bigint> rhs = eval(tok->astOperand2());
383 if (lhs.empty() || rhs.empty()) {
384 if (frontIs(lhs, !then))
385 programMemoryParseCondition(pm, tok->astOperand2(), endTok, settings, then);
386 else if (frontIs(rhs, !then))
387 programMemoryParseCondition(pm, tok->astOperand1(), endTok, settings, then);
388 else
389 pm.setIntValue(tok, 0, then);
390 }
391 } else if (tok && tok->exprId() > 0) {
392 if (endTok && findExpressionChanged(tok, tok->next(), endTok, settings))
393 return;
394 pm.setIntValue(tok, 0, then);
395 const Token* containerTok = settings.library.getContainerFromYield(tok, Library::Container::Yield::EMPTY);
396 if (containerTok)
397 pm.setContainerSizeValue(containerTok, 0, then);

Callers 4

assumeMethod · 0.85
evalSameConditionFunction · 0.85

Calls 14

executeFunction · 0.85
findExpressionChangedFunction · 0.85
frontIsFunction · 0.85
getKnownValueMethod · 0.80
nextMethod · 0.80
getContainerFromYieldMethod · 0.80
setContainerSizeValueMethod · 0.80
astOperand1Method · 0.80
astOperand2Method · 0.80
setIntValueMethod · 0.80
simpleMatchFunction · 0.70
strMethod · 0.45

Tested by

no test coverage detected