| 1422 | } |
| 1423 | |
| 1424 | std::string ValueFlow::lifetimeMessage(const Token *tok, const ValueFlow::Value *val, ErrorPath &errorPath) |
| 1425 | { |
| 1426 | const Token *tokvalue = val ? val->tokvalue : nullptr; |
| 1427 | const Variable *tokvar = tokvalue ? tokvalue->variable() : nullptr; |
| 1428 | const Token *vartok = tokvar ? tokvar->nameToken() : nullptr; |
| 1429 | const bool classVar = tokvar ? (!tokvar->isLocal() && !tokvar->isArgument() && !tokvar->isGlobal()) : false; |
| 1430 | std::string type = lifetimeType(tok, val); |
| 1431 | std::string msg = type; |
| 1432 | if (vartok) { |
| 1433 | if (!classVar) |
| 1434 | errorPath.emplace_back(vartok, "Variable created here."); |
| 1435 | const Variable * var = vartok->variable(); |
| 1436 | if (var) { |
| 1437 | std::string submessage; |
| 1438 | switch (val->lifetimeKind) { |
| 1439 | case ValueFlow::Value::LifetimeKind::SubObject: |
| 1440 | case ValueFlow::Value::LifetimeKind::Object: |
| 1441 | case ValueFlow::Value::LifetimeKind::Address: |
| 1442 | if (type == "pointer") |
| 1443 | submessage = " to local variable"; |
| 1444 | else |
| 1445 | submessage = " that points to local variable"; |
| 1446 | break; |
| 1447 | case ValueFlow::Value::LifetimeKind::Lambda: |
| 1448 | submessage = " that captures local variable"; |
| 1449 | break; |
| 1450 | case ValueFlow::Value::LifetimeKind::Iterator: |
| 1451 | submessage = " to local container"; |
| 1452 | break; |
| 1453 | } |
| 1454 | if (classVar) |
| 1455 | submessage.replace(submessage.find("local"), 5, "member"); |
| 1456 | msg += submessage + " '" + var->name() + "'"; |
| 1457 | } |
| 1458 | } |
| 1459 | return msg; |
| 1460 | } |
| 1461 | |
| 1462 | std::vector<ValueFlow::Value> ValueFlow::getLifetimeObjValues(const Token* tok, bool inconclusive, MathLib::bigint path) |
| 1463 | { |