| 6841 | |
| 6842 | struct ContainerConditionHandler : ConditionHandler { |
| 6843 | std::vector<Condition> parse(const Token* tok, const Settings& settings) const override |
| 6844 | { |
| 6845 | std::vector<Condition> conds; |
| 6846 | parseCompareEachInt(tok, [&](const Token* vartok, ValueFlow::Value true_value, ValueFlow::Value false_value) { |
| 6847 | vartok = settings.library.getContainerFromYield(vartok, Library::Container::Yield::SIZE); |
| 6848 | if (!vartok) |
| 6849 | return; |
| 6850 | true_value.valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE; |
| 6851 | false_value.valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE; |
| 6852 | Condition cond; |
| 6853 | cond.true_values.push_back(std::move(true_value)); |
| 6854 | cond.false_values.push_back(std::move(false_value)); |
| 6855 | cond.vartok = vartok; |
| 6856 | conds.push_back(std::move(cond)); |
| 6857 | }); |
| 6858 | if (!conds.empty()) |
| 6859 | return conds; |
| 6860 | |
| 6861 | const Token* vartok = nullptr; |
| 6862 | |
| 6863 | // Empty check |
| 6864 | if (tok->str() == "(") { |
| 6865 | vartok = settings.library.getContainerFromYield(tok, Library::Container::Yield::EMPTY); |
| 6866 | // TODO: Handle .size() |
| 6867 | if (!vartok) |
| 6868 | return {}; |
| 6869 | const Token *parent = tok->astParent(); |
| 6870 | while (parent) { |
| 6871 | if (Token::Match(parent, "%comp%")) |
| 6872 | return {}; |
| 6873 | parent = parent->astParent(); |
| 6874 | } |
| 6875 | ValueFlow::Value value(tok, 0LL); |
| 6876 | value.valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE; |
| 6877 | Condition cond; |
| 6878 | cond.true_values.emplace_back(value); |
| 6879 | cond.false_values.emplace_back(std::move(value)); |
| 6880 | cond.vartok = vartok; |
| 6881 | cond.inverted = true; |
| 6882 | return {std::move(cond)}; |
| 6883 | } |
| 6884 | // String compare |
| 6885 | if (Token::Match(tok, "==|!=")) { |
| 6886 | const Token *strtok = nullptr; |
| 6887 | if (Token::Match(tok->astOperand1(), "%str%")) { |
| 6888 | strtok = tok->astOperand1(); |
| 6889 | vartok = tok->astOperand2(); |
| 6890 | } else if (Token::Match(tok->astOperand2(), "%str%")) { |
| 6891 | strtok = tok->astOperand2(); |
| 6892 | vartok = tok->astOperand1(); |
| 6893 | } |
| 6894 | if (!strtok) |
| 6895 | return {}; |
| 6896 | if (!astIsContainer(vartok)) |
| 6897 | return {}; |
| 6898 | ValueFlow::Value value(tok, Token::getStrLength(strtok)); |
| 6899 | value.valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE; |
| 6900 | Condition cond; |
nothing calls this directly
no test coverage detected