diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 2848c0e87..473f8c000 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -5643,12 +5643,15 @@ static void valueFlowForwardConst(Token* start, if (v.tokvalue->varId() != var->declarationId()) continue; for (ValueFlow::Value value : values) { + if (!v.isKnown() && value.isImpossible()) + continue; if (v.intvalue != 0) { if (!value.isIntValue()) continue; value.intvalue += v.intvalue; } - value.valueKind = v.valueKind; + if (!value.isImpossible()) + value.valueKind = v.valueKind; value.bound = v.bound; value.errorPath.insert(value.errorPath.end(), v.errorPath.cbegin(), v.errorPath.cend()); setTokenValue(tok, std::move(value), settings); diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 786ba311c..d603bd5ed 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -4722,6 +4722,16 @@ private: " (it != end) && *it;\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + // #12116 + check("void f(int n) {\n" + " for (int i = 0; i < N; ++i) {\n" + " if (i < n) {}\n" + " else if (i > n) {}\n" + " else {}\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void alwaysTrueInfer() { diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 94479182c..02231bc64 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -8174,6 +8174,18 @@ private: " }\n" "}\n"; ASSERT_EQUALS(true, testValueOfXImpossible(code, 4U, -1)); + + code = "void f(int N, int z) {\n" + " std::vector a(N);\n" + " int m = -1;\n" + " m = 0;\n" + " for (int k = 0; k < N; k++) {\n" + " int x = m + k;\n" + " if (z == a[x]) {}\n" + " }\n" + "}\n"; + ASSERT_EQUALS(true, testValueOfXImpossible(code, 7U, -1)); + ASSERT_EQUALS(false, testValueOfXKnown(code, 7U, -1)); } void valueFlowImpossibleUnknownConstant()