diff --git a/lib/astutils.cpp b/lib/astutils.cpp index fb5a2934b..69c1ceefd 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -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(); + if (Token::Match(varDeclEndToken, "; %var%") && varDeclEndToken->next() == tok) return true; return false; } @@ -1068,16 +1069,17 @@ std::vector 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{}; - 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)}}; diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index 2fc6efa0b..526555b40 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -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); } diff --git a/lib/checkother.cpp b/lib/checkother.cpp index e9b582e5a..2233ca620 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -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 diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 6cf0f4f41..1f8e5ad17 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -3340,14 +3340,15 @@ static std::vector 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) || @@ -4021,6 +4022,8 @@ struct LifetimeStore { return; if (!argtok) return; + if (!tok) + return; for (const ValueFlow::Value &v : argtok->values()) { if (!v.isLifetimeValue()) continue; @@ -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;