From 990e60d9c23ad75d0676a95c19ee5a0adca3b0e3 Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 11 Dec 2023 16:48:08 -0600 Subject: [PATCH 1/3] Fix 12032: False positive: uninitialized variable, flags with same value --- lib/programmemory.cpp | 34 ++++++++++++++++++++++++++++++---- test/testvalueflow.cpp | 16 ++++++++++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 3a140424fd9..2901b00585f 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -1637,6 +1637,14 @@ namespace { return *it; } + static bool updateValue(ValueFlow::Value& v, ValueFlow::Value x) + { + const bool returnValue = !x.isUninitValue() && !x.isImpossible(); + if(v.isUninitValue() || returnValue) + v = std::move(x); + return returnValue; + } + ValueFlow::Value execute(const Token* expr) { depth--; @@ -1645,13 +1653,31 @@ namespace { }}; if (depth < 0) return unknown(); - ValueFlow::Value v = executeImpl(expr); - if (!v.isUninitValue()) + ValueFlow::Value v = unknown(); + if (updateValue(v, executeImpl(expr))) return v; if (!expr) return v; - if (expr->exprId() > 0 && pm->hasValue(expr->exprId())) - return pm->at(expr->exprId()); + if (expr->exprId() > 0 && pm->hasValue(expr->exprId())) { + if (updateValue(v, pm->at(expr->exprId()))) + return v; + } + // Find symbolic values + for (const ValueFlow::Value& value : expr->values()) { + if (!value.isSymbolicValue()) + continue; + if (!value.isKnown()) + continue; + if (value.tokvalue->exprId() > 0 && !pm->hasValue(value.tokvalue->exprId())) + continue; + ValueFlow::Value v2 = pm->at(value.tokvalue->exprId()); + if(!v2.isIntValue() && value.intvalue != 0) + continue; + v2.intvalue += value.intvalue; + if (updateValue(v, std::move(v2))) + return v; + return v2; + } if (const ValueFlow::Value* value = getImpossibleValue(expr)) return *value; return v; diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 315cc73c3d0..01c8bf676ca 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -5645,6 +5645,22 @@ class TestValueFlow : public TestFixture { values = tokenValues(code, "x <", ValueFlow::Value::ValueType::UNINIT); ASSERT_EQUALS(0, values.size()); + code = "void getX(int *p);\n" + "bool do_something();\n" + "void foo() {\n" + " int x;\n" + " bool flag;\n" + " bool success;\n" + " success = do_something();\n" + " flag = success;\n" + " if (success == true) {\n" + " getX(&x);\n" + " }\n" + " for (int i = 0; (flag == true) && (i < x); ++i) {}\n" + "}\n"; + values = tokenValues(code, "x ) ; ++ i", ValueFlow::Value::ValueType::UNINIT); + ASSERT_EQUALS(0, values.size()); + code = "void g(bool *result, size_t *buflen) {\n" // #12091 " if (*result && *buflen >= 5) {}\n" // <- *buflen might not be initialized "}\n" From a7073962ac31a27ae2e4e1e32c0f4a20b9cd2756 Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 11 Dec 2023 16:48:38 -0600 Subject: [PATCH 2/3] Format --- lib/programmemory.cpp | 4 ++-- test/testvalueflow.cpp | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 2901b00585f..1da77888e57 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -1640,7 +1640,7 @@ namespace { static bool updateValue(ValueFlow::Value& v, ValueFlow::Value x) { const bool returnValue = !x.isUninitValue() && !x.isImpossible(); - if(v.isUninitValue() || returnValue) + if (v.isUninitValue() || returnValue) v = std::move(x); return returnValue; } @@ -1671,7 +1671,7 @@ namespace { if (value.tokvalue->exprId() > 0 && !pm->hasValue(value.tokvalue->exprId())) continue; ValueFlow::Value v2 = pm->at(value.tokvalue->exprId()); - if(!v2.isIntValue() && value.intvalue != 0) + if (!v2.isIntValue() && value.intvalue != 0) continue; v2.intvalue += value.intvalue; if (updateValue(v, std::move(v2))) diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 01c8bf676ca..41df5a00976 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -5646,18 +5646,18 @@ class TestValueFlow : public TestFixture { ASSERT_EQUALS(0, values.size()); code = "void getX(int *p);\n" - "bool do_something();\n" - "void foo() {\n" - " int x;\n" - " bool flag;\n" - " bool success;\n" - " success = do_something();\n" - " flag = success;\n" - " if (success == true) {\n" - " getX(&x);\n" - " }\n" - " for (int i = 0; (flag == true) && (i < x); ++i) {}\n" - "}\n"; + "bool do_something();\n" + "void foo() {\n" + " int x;\n" + " bool flag;\n" + " bool success;\n" + " success = do_something();\n" + " flag = success;\n" + " if (success == true) {\n" + " getX(&x);\n" + " }\n" + " for (int i = 0; (flag == true) && (i < x); ++i) {}\n" + "}\n"; values = tokenValues(code, "x ) ; ++ i", ValueFlow::Value::ValueType::UNINIT); ASSERT_EQUALS(0, values.size()); From 563776f9bd856e3e30dd8ab747928a498fb06fa6 Mon Sep 17 00:00:00 2001 From: Paul Date: Sat, 16 Dec 2023 11:55:12 -0600 Subject: [PATCH 3/3] Fix use after move --- lib/programmemory.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 1da77888e57..81890770c5d 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -1674,8 +1674,6 @@ namespace { if (!v2.isIntValue() && value.intvalue != 0) continue; v2.intvalue += value.intvalue; - if (updateValue(v, std::move(v2))) - return v; return v2; } if (const ValueFlow::Value* value = getImpossibleValue(expr))