diff --git a/lib/exprengine.cpp b/lib/exprengine.cpp index 2f239fd7c..4da679ce7 100644 --- a/lib/exprengine.cpp +++ b/lib/exprengine.cpp @@ -2363,7 +2363,19 @@ void ExprEngine::runChecks(ErrorLogger *errorLogger, const Tokenizer *tokenizer, std::function uninit = [=](const Token *tok, const ExprEngine::Value &value, ExprEngine::DataBase *dataBase) { if (!tok->astParent()) return; - if (!value.isUninit()) + + std::string uninitStructMember; + if (const auto* structValue = dynamic_cast(&value)) { + uninitStructMember = structValue->getUninitStructMember(); + + // uninitialized struct member => is there data copy of struct.. + if (!uninitStructMember.empty()) { + if (!Token::Match(tok->astParent(), "[=,(]")) + return; + } + } + + if (!value.isUninit() && uninitStructMember.empty()) return; // lhs in assignment @@ -2420,6 +2432,11 @@ void ExprEngine::runChecks(ErrorLogger *errorLogger, const Tokenizer *tokenizer, dataBase->addError(tok->linenr()); std::list callstack{tok}; + if (!uninitStructMember.empty()) { + ErrorMessage errmsg(callstack, &tokenizer->list, Severity::SeverityType::error, "bughuntingUninitStructMember", "Cannot determine that '" + tok->expressionString() + "." + uninitStructMember + "' is initialized", CWE_USE_OF_UNINITIALIZED_VARIABLE, false); + errorLogger->reportErr(errmsg); + return; + } ErrorMessage errmsg(callstack, &tokenizer->list, Severity::SeverityType::error, "bughuntingUninit", "Cannot determine that '" + tok->expressionString() + "' is initialized", CWE_USE_OF_UNINITIALIZED_VARIABLE, false); errorLogger->reportErr(errmsg); }; diff --git a/lib/exprengine.h b/lib/exprengine.h index b76a3f650..43f99dded 100644 --- a/lib/exprengine.h +++ b/lib/exprengine.h @@ -231,6 +231,15 @@ namespace ExprEngine { auto it = member.find(n); return (it == member.end()) ? ValuePtr() : it->second; } + + std::string getUninitStructMember() const { + for (auto memberNameValue: member) { + if (memberNameValue.second && memberNameValue.second->isUninit()) + return memberNameValue.first; + } + return std::string(); + } + std::map member; };