Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions lib/astutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,8 @@ bool isVariableDecl(const Token* tok)
return false;
if (var->nameToken() == tok)
return true;
if (Token::Match(var->declEndToken(), "; %var%") && var->declEndToken()->next() == tok)
const Token * const varDeclEndToken = var->declEndToken();
Comment thread
danmar marked this conversation as resolved.
if (Token::Match(varDeclEndToken, "; %var%") && varDeclEndToken->next() == tok)
return true;
return false;
}
Expand Down Expand Up @@ -1068,16 +1069,17 @@ std::vector<ReferenceToken> followAllReferences(const Token* tok,
if (var->nameToken() == tok || isStructuredBindingVariable(var)) {
return {{tok, std::move(errors)}};
} else if (var->isReference() || var->isRValueReference()) {
if (!var->declEndToken())
const Token * const varDeclEndToken = var->declEndToken();
if (!varDeclEndToken)
return {{tok, std::move(errors)}};
if (var->isArgument()) {
errors.emplace_back(var->declEndToken(), "Passed to reference.");
errors.emplace_back(varDeclEndToken, "Passed to reference.");
return {{tok, std::move(errors)}};
} else if (Token::simpleMatch(var->declEndToken(), "=")) {
if (astHasToken(var->declEndToken(), tok))
} else if (Token::simpleMatch(varDeclEndToken, "=")) {
if (astHasToken(varDeclEndToken, tok))
return std::vector<ReferenceToken>{};
errors.emplace_back(var->declEndToken(), "Assigned to reference.");
const Token *vartok = var->declEndToken()->astOperand2();
errors.emplace_back(varDeclEndToken, "Assigned to reference.");
const Token *vartok = varDeclEndToken->astOperand2();
if (vartok == tok || (!temporary && isTemporary(true, vartok, nullptr, true) &&
(var->isConst() || var->isRValueReference())))
return {{tok, std::move(errors)}};
Expand Down
7 changes: 4 additions & 3 deletions lib/checkautovariables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,11 +471,12 @@ static bool isEscapedReference(const Variable* var)
return false;
if (!var->isReference())
return false;
if (!var->declEndToken())
const Token * const varDeclEndToken = var->declEndToken();
if (!varDeclEndToken)
return false;
if (!Token::simpleMatch(var->declEndToken(), "="))
if (!Token::simpleMatch(varDeclEndToken, "="))
return false;
const Token* vartok = var->declEndToken()->astOperand2();
const Token* vartok = varDeclEndToken->astOperand2();
return !isTemporary(true, vartok, nullptr, false);
}

Expand Down
3 changes: 2 additions & 1 deletion lib/checkother.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1297,7 +1297,8 @@ void CheckOther::checkPassByReference()
if (var->scope() && var->scope()->function->arg->link()->strAt(-1) == "...")
continue; // references could not be used as va_start parameters (#5824)

if ((var->declEndToken() && var->declEndToken()->isExternC()) ||
const Token * const varDeclEndToken = var->declEndToken();
if ((varDeclEndToken && varDeclEndToken->isExternC()) ||
(var->scope() && var->scope()->function && var->scope()->function->tokenDef && var->scope()->function->tokenDef->isExternC()))
continue; // references cannot be used in functions in extern "C" blocks

Expand Down
16 changes: 10 additions & 6 deletions lib/valueflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3340,14 +3340,15 @@ static std::vector<LifetimeToken> getLifetimeTokens(const Token* tok,
return {{tok, std::move(errorPath)}};
if (var && var->declarationId() == tok->varId()) {
if (var->isReference() || var->isRValueReference()) {
if (!var->declEndToken())
const Token * const varDeclEndToken = var->declEndToken();
if (!varDeclEndToken)
return {{tok, true, std::move(errorPath)}};
if (var->isArgument()) {
errorPath.emplace_back(var->declEndToken(), "Passed to reference.");
errorPath.emplace_back(varDeclEndToken, "Passed to reference.");
return {{tok, true, std::move(errorPath)}};
} else if (Token::simpleMatch(var->declEndToken(), "=")) {
errorPath.emplace_back(var->declEndToken(), "Assigned to reference.");
const Token *vartok = var->declEndToken()->astOperand2();
} else if (Token::simpleMatch(varDeclEndToken, "=")) {
errorPath.emplace_back(varDeclEndToken, "Assigned to reference.");
const Token *vartok = varDeclEndToken->astOperand2();
const bool temporary = isTemporary(true, vartok, nullptr, true);
const bool nonlocal = var->isStatic() || var->isGlobal();
if (vartok == tok || (nonlocal && temporary) ||
Expand Down Expand Up @@ -4021,6 +4022,8 @@ struct LifetimeStore {
return;
if (!argtok)
return;
if (!tok)
return;
for (const ValueFlow::Value &v : argtok->values()) {
if (!v.isLifetimeValue())
continue;
Expand All @@ -4031,7 +4034,8 @@ struct LifetimeStore {
er.insert(er.end(), errorPath.begin(), errorPath.end());
if (!var)
continue;
for (const Token *tok3 = tok; tok3 && tok3 != var->declEndToken(); tok3 = tok3->previous()) {
const Token * const varDeclEndToken = var->declEndToken();
for (const Token *tok3 = tok; tok3 && tok3 != varDeclEndToken; tok3 = tok3->previous()) {
if (tok3->varId() == var->declarationId()) {
LifetimeStore{tok3, message, type, inconclusive}.byVal(tok, tokenlist, errorLogger, settings, pred);
break;
Expand Down