| 3932 | } |
| 3933 | |
| 3934 | void CheckOtherImpl::checkAccessOfMovedVariable() |
| 3935 | { |
| 3936 | if (!mTokenizer->isCPP() || mSettings.standards.cpp < Standards::CPP11) |
| 3937 | return; |
| 3938 | if (!mSettings.isPremiumEnabled("accessMoved") && !mSettings.severity.isEnabled(Severity::warning)) |
| 3939 | return; |
| 3940 | logChecker("CheckOther::checkAccessOfMovedVariable"); // c++11,warning |
| 3941 | const bool reportInconclusive = mSettings.certainty.isEnabled(Certainty::inconclusive); |
| 3942 | const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); |
| 3943 | for (const Scope * scope : symbolDatabase->functionScopes) { |
| 3944 | const Token * scopeStart = scope->bodyStart; |
| 3945 | if (scope->function) { |
| 3946 | const Token * memberInitializationStart = scope->function->constructorMemberInitialization(); |
| 3947 | if (memberInitializationStart) |
| 3948 | scopeStart = memberInitializationStart; |
| 3949 | } |
| 3950 | for (const Token* tok = scopeStart->next(); tok != scope->bodyEnd; tok = tok->next()) { |
| 3951 | if (!tok->astParent()) |
| 3952 | continue; |
| 3953 | const ValueFlow::Value * movedValue = tok->getMovedValue(); |
| 3954 | if (!movedValue || movedValue->moveKind == ValueFlow::Value::MoveKind::NonMovedVariable) |
| 3955 | continue; |
| 3956 | if (movedValue->isInconclusive() && !reportInconclusive) |
| 3957 | continue; |
| 3958 | |
| 3959 | bool inconclusive = false; |
| 3960 | bool accessOfMoved = false; |
| 3961 | if (tok->strAt(1) == ".") { |
| 3962 | if (tok->next()->originalName() == "->") |
| 3963 | accessOfMoved = true; |
| 3964 | else |
| 3965 | inconclusive = true; |
| 3966 | } else { |
| 3967 | const ExprUsage usage = getExprUsage(tok, 0, mSettings); |
| 3968 | if (usage == ExprUsage::Used) |
| 3969 | accessOfMoved = true; |
| 3970 | if (usage == ExprUsage::PassedByReference) |
| 3971 | accessOfMoved = !isVariableChangedByFunctionCall(tok, 0, mSettings, &inconclusive); |
| 3972 | else if (usage == ExprUsage::Inconclusive) |
| 3973 | inconclusive = true; |
| 3974 | } |
| 3975 | if (accessOfMoved || (inconclusive && reportInconclusive)) |
| 3976 | accessMovedError(tok, tok->str(), movedValue, inconclusive || movedValue->isInconclusive()); |
| 3977 | } |
| 3978 | } |
| 3979 | } |
| 3980 | |
| 3981 | void CheckOtherImpl::accessMovedError(const Token *tok, const std::string &varname, const ValueFlow::Value *value, bool inconclusive) |
| 3982 | { |
no test coverage detected