| 6015 | } |
| 6016 | |
| 6017 | static void valueFlowUninit(TokenList& tokenlist, ErrorLogger& errorLogger, const Settings& settings) |
| 6018 | { |
| 6019 | for (Token *tok = tokenlist.front(); tok; tok = tok->next()) { |
| 6020 | if (!tok->scope()->isExecutable()) |
| 6021 | continue; |
| 6022 | if (!Token::Match(tok, "%var% ;|[")) |
| 6023 | continue; |
| 6024 | const Variable* var = tok->variable(); |
| 6025 | if (!var) |
| 6026 | continue; |
| 6027 | if (var->nameToken() != tok || var->isInit()) |
| 6028 | continue; |
| 6029 | if (!needsInitialization(var)) |
| 6030 | continue; |
| 6031 | if (!var->isLocal() || var->isStatic() || var->isExtern() || var->isReference() || var->isThrow()) |
| 6032 | continue; |
| 6033 | |
| 6034 | ValueFlow::Value uninitValue; |
| 6035 | uninitValue.setKnown(); |
| 6036 | uninitValue.valueType = ValueFlow::Value::ValueType::UNINIT; |
| 6037 | uninitValue.tokvalue = tok; |
| 6038 | if (var->isArray()) |
| 6039 | uninitValue.indirect = var->dimensions().size(); |
| 6040 | |
| 6041 | bool partial = false; |
| 6042 | |
| 6043 | Token* start = findStartToken(var, tok->next(), settings.library); |
| 6044 | |
| 6045 | std::map<Token*, ValueFlow::Value> partialReads; |
| 6046 | if (const Scope* scope = var->typeScope()) { |
| 6047 | if (Token::findsimplematch(scope->bodyStart, "union", scope->bodyEnd)) |
| 6048 | continue; |
| 6049 | for (const Variable& memVar : scope->varlist) { |
| 6050 | if (!memVar.isPublic()) |
| 6051 | continue; |
| 6052 | // Skip array since we can't track partial initialization from nested subexpressions |
| 6053 | if (memVar.isArray()) |
| 6054 | continue; |
| 6055 | if (!needsInitialization(&memVar)) { |
| 6056 | if (!var->isPointer()) |
| 6057 | partial = true; |
| 6058 | continue; |
| 6059 | } |
| 6060 | auto partialReadsAnalyzer = std::make_shared<PartialReadContainer>(); |
| 6061 | auto analyzer = makeMemberExpressionAnalyzer(memVar.nameToken()->str(), tok, uninitValue, partialReadsAnalyzer, settings); |
| 6062 | valueFlowGenericForward(start, tok->scope()->bodyEnd, analyzer, tokenlist, errorLogger, settings); |
| 6063 | |
| 6064 | for (auto&& p : *partialReadsAnalyzer) { |
| 6065 | Token* tok2 = p.first; |
| 6066 | const ValueFlow::Value& v = p.second; |
| 6067 | // Try to insert into map |
| 6068 | auto pp = partialReads.emplace(tok2, v); |
| 6069 | ValueFlow::Value& v2 = pp.first->second; |
| 6070 | const bool inserted = pp.second; |
| 6071 | // Merge the two values if it is already in map |
| 6072 | if (!inserted) { |
| 6073 | if (v.valueType != v2.valueType) |
| 6074 | continue; |