From 1d5e3e4f0c4180259938252f22614ffbe08c3351 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 20 Oct 2017 17:31:58 +0200 Subject: [PATCH] Fixed #8247 (False positive knownConditionTrueFalse) --- lib/valueflow.cpp | 19 ++++++++++++------- test/testvalueflow.cpp | 11 +++++++---- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index de3ce23e1..8c0267698 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -265,7 +265,7 @@ static ValueFlow::Value castValue(ValueFlow::Value value, const ValueType::Sign value.valueType = ValueFlow::Value::INT; value.intvalue = value.floatValue; } - if (bit < 64) { + if (bit < MathLib::bigint_bits) { value.intvalue &= (1ULL << bit) - 1ULL; if (sign == ValueType::Sign::SIGNED && value.intvalue & (1ULL << (bit - 1ULL))) { value.intvalue |= ~((1ULL << bit) - 1ULL); @@ -484,7 +484,7 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti result.intvalue = f ? (floatValue1 > floatValue2) : (value1->intvalue > value2->intvalue); else if (parent->str() == ">=") result.intvalue = f ? (floatValue1 >= floatValue2) : (value1->intvalue >= value2->intvalue); - else if (!f && parent->str() == ">>" && value1->intvalue >= 0 && value2->intvalue >= 0 && value2->intvalue < 64) + else if (!f && parent->str() == ">>" && value1->intvalue >= 0 && value2->intvalue >= 0 && value2->intvalue < MathLib::bigint_bits) result.intvalue = value1->intvalue >> value2->intvalue; else break; @@ -499,7 +499,7 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti result.intvalue = f ? (floatValue1 < floatValue2) : (value1->intvalue < value2->intvalue); else if (parent->str() == "<=") result.intvalue = f ? (floatValue1 <= floatValue2) : (value1->intvalue <= value2->intvalue); - else if (!f && parent->str() == "<<" && value1->intvalue >= 0 && value2->intvalue >= 0 && value2->intvalue < 64) + else if (!f && parent->str() == "<<" && value1->intvalue >= 0 && value2->intvalue >= 0 && value2->intvalue < MathLib::bigint_bits) result.intvalue = value1->intvalue << value2->intvalue; else break; @@ -569,8 +569,8 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti else if (tok->valueType()->type == ValueType::Type::LONG) bits = settings->long_bit; } - if (bits > 0 && bits < 64) - v.intvalue &= (1ULL< 0 && bits < MathLib::bigint_bits) + v.intvalue &= (((MathLib::biguint)1)<next()->str() + ": " + vartok->str() + " is " + tok->next()->str() + " here."); values.back().errorPath.push_back(ErrorPathItem(tok, info)); + bool known = false; if ((Token::simpleMatch(tok->previous(), "{") || Token::simpleMatch(tok->tokAt(-2), "break ;")) && !Token::Match(tok->tokAt(3), ";| case")) - values.back().setKnown(); + known = true; while (Token::Match(tok->tokAt(3), ";| case %num% :")) { + known = false; tok = tok->tokAt(3); if (!tok->isName()) tok = tok->next(); @@ -2914,8 +2916,11 @@ static void valueFlowSwitchVariable(TokenList *tokenlist, SymbolDatabase* symbol errorLogger, settings); } - if (vartok->variable()->scope()) // #7257 + if (vartok->variable()->scope()) { + if (known) + values.back().setKnown(); valueFlowForward(tok->tokAt(3), vartok->variable()->scope()->classEnd, vartok->variable(), vartok->varId(), values, values.back().isKnown(), false, tokenlist, errorLogger, settings); + } } } } diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 4a6588e58..3f1050c27 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -1874,7 +1874,7 @@ private: void valueFlowSwitchVariable() { const char *code; code = "void f(int x) {\n" - " a = x;\n" // <- x can be 14 + " a = x - 1;\n" // <- x can be 14 " switch (x) {\n" " case 14: a=x+2; break;\n" // <- x is 14 " };\n" @@ -1884,10 +1884,13 @@ private: ASSERT_EQUALS(true, testConditionalValueOfX(code, 4U, 14)); ASSERT_EQUALS(true, testConditionalValueOfX(code, 6U, 14)); - ValueFlow::Value value = valueOfTok(code, "+"); - ASSERT_EQUALS(16, value.intvalue); - ASSERT(value.isKnown()); + ValueFlow::Value value1 = valueOfTok(code, "-"); + ASSERT_EQUALS(13, value1.intvalue); + ASSERT(!value1.isKnown()); + ValueFlow::Value value2 = valueOfTok(code, "+"); + ASSERT_EQUALS(16, value2.intvalue); + ASSERT(value2.isKnown()); } void valueFlowForLoop() {