| 2036 | } |
| 2037 | |
| 2038 | static bool removeContradiction(std::list<ValueFlow::Value>& values) |
| 2039 | { |
| 2040 | bool result = false; |
| 2041 | for (auto itx = values.begin(); itx != values.end(); ++itx) { |
| 2042 | if (itx->isNonValue()) |
| 2043 | continue; |
| 2044 | |
| 2045 | auto ity = itx; |
| 2046 | ++ity; |
| 2047 | for (; ity != values.end(); ++ity) { |
| 2048 | if (ity->isNonValue()) |
| 2049 | continue; |
| 2050 | if (*itx == *ity) |
| 2051 | continue; |
| 2052 | if (itx->valueType != ity->valueType) |
| 2053 | continue; |
| 2054 | if (itx->isImpossible() == ity->isImpossible()) |
| 2055 | continue; |
| 2056 | if (itx->isSymbolicValue() && !ValueFlow::Value::sameToken(itx->tokvalue, ity->tokvalue)) |
| 2057 | continue; |
| 2058 | if (!itx->equalValue(*ity)) { |
| 2059 | auto compare = [](const std::list<ValueFlow::Value>::const_iterator& x, const std::list<ValueFlow::Value>::const_iterator& y) { |
| 2060 | return x->compareValue(*y, less{}); |
| 2061 | }; |
| 2062 | auto itMax = std::max(itx, ity, compare); |
| 2063 | auto itMin = std::min(itx, ity, compare); |
| 2064 | // TODO: Adjust non-points instead of removing them |
| 2065 | if (itMax->isImpossible() && itMax->bound == ValueFlow::Value::Bound::Upper) { |
| 2066 | values.erase(itMin); |
| 2067 | return true; |
| 2068 | } |
| 2069 | if (itMin->isImpossible() && itMin->bound == ValueFlow::Value::Bound::Lower) { |
| 2070 | values.erase(itMax); |
| 2071 | return true; |
| 2072 | } |
| 2073 | continue; |
| 2074 | } |
| 2075 | const bool removex = !itx->isImpossible() || ity->isKnown(); |
| 2076 | const bool removey = !ity->isImpossible() || itx->isKnown(); |
| 2077 | if (itx->bound == ity->bound) { |
| 2078 | if (removex) |
| 2079 | values.erase(itx); |
| 2080 | if (removey) |
| 2081 | values.erase(ity); |
| 2082 | // itx and ity are invalidated |
| 2083 | return true; |
| 2084 | } |
| 2085 | result = removex || removey; |
| 2086 | bool bail = false; |
| 2087 | if (removex && removePointValue(values, itx)) |
| 2088 | bail = true; |
| 2089 | if (removey && removePointValue(values, ity)) |
| 2090 | bail = true; |
| 2091 | if (bail) |
| 2092 | return true; |
| 2093 | } |
| 2094 | } |
| 2095 | return result; |
no test coverage detected