| 2220 | } |
| 2221 | |
| 2222 | bool Token::addValue(const ValueFlow::Value &value) |
| 2223 | { |
| 2224 | if (value.isKnown() && mImpl->mValues) { |
| 2225 | // Clear all other values of the same type since value is known |
| 2226 | mImpl->mValues->remove_if([&](const ValueFlow::Value& x) { |
| 2227 | return sameValueType(x, value); |
| 2228 | }); |
| 2229 | } |
| 2230 | |
| 2231 | // Don't add a value if its already known |
| 2232 | if (!value.isKnown() && mImpl->mValues && |
| 2233 | std::any_of(mImpl->mValues->begin(), mImpl->mValues->end(), [&](const ValueFlow::Value& x) { |
| 2234 | return x.isKnown() && sameValueType(x, value) && !x.equalValue(value); |
| 2235 | })) |
| 2236 | return false; |
| 2237 | |
| 2238 | // assert(value.isKnown() || !mImpl->mValues || std::none_of(mImpl->mValues->begin(), mImpl->mValues->end(), |
| 2239 | // [&](const ValueFlow::Value& x) { |
| 2240 | // return x.isKnown() && sameValueType(x, value); |
| 2241 | // })); |
| 2242 | |
| 2243 | if (mImpl->mValues) { |
| 2244 | // Don't handle more than 10 values for performance reasons |
| 2245 | // TODO: add setting? |
| 2246 | if (mImpl->mValues->size() >= 10U) |
| 2247 | return false; |
| 2248 | |
| 2249 | // if value already exists, don't add it again |
| 2250 | auto it = mImpl->mValues->begin(); |
| 2251 | for (; it != mImpl->mValues->end(); ++it) { |
| 2252 | // different types => continue |
| 2253 | if (it->valueType != value.valueType) |
| 2254 | continue; |
| 2255 | |
| 2256 | if (it->isImpossible() != value.isImpossible()) |
| 2257 | continue; |
| 2258 | |
| 2259 | // different value => continue |
| 2260 | if (!it->equalValue(value)) |
| 2261 | continue; |
| 2262 | |
| 2263 | if ((value.isTokValue() || value.isLifetimeValue()) && (it->tokvalue != value.tokvalue) && (it->tokvalue->str() != value.tokvalue->str())) |
| 2264 | continue; |
| 2265 | |
| 2266 | // same value, but old value is inconclusive so replace it |
| 2267 | if (it->isInconclusive() && !value.isInconclusive() && !value.isImpossible()) { |
| 2268 | *it = value; |
| 2269 | if (it->varId == 0) |
| 2270 | it->varId = mImpl->mVarId; |
| 2271 | break; |
| 2272 | } |
| 2273 | |
| 2274 | // Same value already exists, don't add new value |
| 2275 | return false; |
| 2276 | } |
| 2277 | |
| 2278 | // Add value |
| 2279 | if (it == mImpl->mValues->end()) { |