From 5d25050b0664f604d3c60e75091d704e3b350abf Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Thu, 10 Feb 2022 13:22:14 -0600 Subject: [PATCH] Fix 10788: False positive: zerodivcond when using an assert (#3816) --- lib/programmemory.cpp | 27 ++++++++++++++++++++++++++- test/testvalueflow.cpp | 7 +++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 34c2e215e..ff3e77a4c 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -559,7 +559,9 @@ static ValueFlow::Value evaluate(const std::string& op, const ValueFlow::Value& return result; } -static ValueFlow::Value execute(const Token* expr, ProgramMemory& pm, const Settings* settings = nullptr) +static ValueFlow::Value execute(const Token* expr, ProgramMemory& pm, const Settings* settings = nullptr); + +static ValueFlow::Value executeImpl(const Token* expr, ProgramMemory& pm, const Settings* settings) { ValueFlow::Value unknown = ValueFlow::Value::unknown(); const ValueFlow::Value* value = nullptr; @@ -743,6 +745,29 @@ static ValueFlow::Value execute(const Token* expr, ProgramMemory& pm, const Sett return unknown; } +static ValueFlow::Value execute(const Token* expr, ProgramMemory& pm, const Settings* settings) +{ + ValueFlow::Value v = executeImpl(expr, pm, settings); + if (!v.isUninitValue()) + return v; + if (!expr) + return v; + if (pm.hasValue(expr->exprId())) + return pm.at(expr->exprId()); + // Find symbolic values + for (const ValueFlow::Value& value : expr->values()) { + if (!value.isSymbolicValue()) + continue; + if (!pm.hasValue(value.tokvalue->exprId())) + continue; + ValueFlow::Value v2 = pm.at(value.tokvalue->exprId()); + v2.intvalue += value.intvalue; + v2.valueKind = value.valueKind; + return v2; + } + return v; +} + void execute(const Token* expr, ProgramMemory* const programMemory, MathLib::bigint* result, diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 69e273f54..9ae39f559 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -6933,6 +6933,13 @@ private: "}\n"; ASSERT_EQUALS(false, testValueOfX(code, 4U, 71)); TODO_ASSERT_EQUALS(true, false, testValueOfX(code, 4U, 56)); + + code = "int b(int a) {\n" + " unsigned long x = a ? 6 : 4;\n" + " assert(x < 6 && x > 0);\n" + " return 1 / x;\n" + "}\n"; + ASSERT_EQUALS(false, testValueOfX(code, 4U, 0)); } void valueFlowSymbolicIdentity()