From 36b9e545ac26d3b8c40bd1548f54ed5ca67e84f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 13 Jul 2020 20:23:44 +0200 Subject: [PATCH] Bug hunting; more bailout warnings in uninit check --- lib/bughuntingchecks.cpp | 31 ++++++++++++++++++++----------- lib/exprengine.h | 2 -- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/lib/bughuntingchecks.cpp b/lib/bughuntingchecks.cpp index 87ca9ee34..39062cfac 100644 --- a/lib/bughuntingchecks.cpp +++ b/lib/bughuntingchecks.cpp @@ -87,7 +87,7 @@ static void divByZero(const Token *tok, const ExprEngine::Value &value, ExprEngi return; if (tok->isImpossibleIntValue(0)) return; - if (value.isUninit()) + if (value.isUninit() && value.type != ExprEngine::ValueType::BailoutValue) return; float f = getKnownFloatValue(tok, 0.0f); if (f > 0.0f || f < 0.0f) @@ -216,22 +216,16 @@ static void uninit(const Token *tok, const ExprEngine::Value &value, ExprEngine: if (value.type == ExprEngine::ValueType::BailoutValue) { if (tok->hasKnownValue()) return; - if (tok->function()) - return; - if (Token::Match(tok, "<<|>>|,")) - // Only warn about the operands + if (!tok->variable()) + // FIXME return; + // lhs for scope operator if (Token::Match(tok, "%name% ::")) return; if (tok->astParent()->str() == "::" && tok == tok->astParent()->astOperand1()) return; - if (tok->str() == "(") - // cast: result is not uninitialized if expression is initialized - // function: does not return a uninitialized value - return; - // Containers are not uninitialized std::vector tokens{tok, tok->astOperand1(), tok->astOperand2()}; if (Token::Match(tok->previous(), ". %name%")) @@ -242,15 +236,30 @@ static void uninit(const Token *tok, const ExprEngine::Value &value, ExprEngine: } const Variable *var = tok->variable(); + if (var && var->nameToken() == tok) + return; + if (var && !var->isLocal()) + return; // FIXME if (var && !var->isPointer()) { if (!var->isLocal() || var->isStatic()) return; } - if (var && (Token::Match(var->nameToken(), "%name% =") || Token::Match(var->nameToken(), "%varid% ; %varid% =", var->declarationId()))) + if (var && (Token::Match(var->nameToken(), "%name% [=:]") || Token::Match(var->nameToken(), "%varid% ; %varid% =", var->declarationId()))) return; if (var && var->nameToken() == tok) return; + // Are there unconditional assignment? + if (var && Token::Match(var->nameToken(), "%varid% ;| %varid%| =", tok->varId())) + return; + for (const Token *prev = tok->previous(); prev; prev = prev->previous()) { + if (!precedes(var->nameToken(), prev)) + break; + if (prev->str() == "}") + prev = prev->link(); + if (Token::Match(prev, "%varid% =", tok->varId())) + return; + } } // Uninitialized function argument diff --git a/lib/exprengine.h b/lib/exprengine.h index cff8d536f..46966d610 100644 --- a/lib/exprengine.h +++ b/lib/exprengine.h @@ -317,11 +317,9 @@ namespace ExprEngine { bool isEqual(DataBase * /*dataBase*/, int /*value*/) const OVERRIDE { return true; } - /* FIXME: This is too noisy bool isUninit() const OVERRIDE { return true; } - */ }; typedef std::function Callback;