diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 30f10794855..d276ade9754 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -429,6 +429,12 @@ bool isStlStringType(const Token* tok) (Token::simpleMatch(tok, "std :: basic_string <") && !Token::simpleMatch(tok->linkAt(3), "> ::")); } +bool isVoidCast(const Token* tok) +{ + return Token::simpleMatch(tok, "(") && tok->isCast() && tok->valueType() && + tok->valueType()->type == ValueType::Type::VOID && tok->valueType()->pointer == 0; +} + bool isTemporary(const Token* tok, const Library* library, bool unknown) { if (!tok) diff --git a/lib/astutils.h b/lib/astutils.h index f7a245c0430..1ec6a39bb1d 100644 --- a/lib/astutils.h +++ b/lib/astutils.h @@ -188,6 +188,8 @@ const Token * astIsVariableComparison(const Token *tok, const std::string &comp, bool isVariableDecl(const Token* tok); bool isStlStringType(const Token* tok); +bool isVoidCast(const Token* tok); + bool isTemporary(const Token* tok, const Library* library, bool unknown = false); const Token* previousBeforeAstLeftmostLeaf(const Token* tok); diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 7a06f66f644..d876256f034 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1641,6 +1641,21 @@ static bool isVariableMutableInInitializer(const Token* start, const Token * end return false; } +static bool isCastToVoid(const Variable* var) +{ + if (!var) + return false; + if (!var->scope()) + return false; + for (const Token* tok = var->scope()->bodyStart; tok != var->scope()->bodyEnd; tok = tok->next()) { + if (tok->varId() != var->declarationId()) + continue; + if (isVoidCast(tok->astParent())) + return true; + } + return false; +} + void CheckOther::checkConstVariable() { if ((!mSettings->severity.isEnabled(Severity::style) || mTokenizer->isC()) && !mSettings->isPremiumEnabled("constVariable")) @@ -1689,6 +1704,8 @@ void CheckOther::checkConstVariable() continue; if (isStructuredBindingVariable(var)) // TODO: check all bound variables continue; + if (isCastToVoid(var)) + continue; if (isVariableChanged(var, *mSettings)) continue; const bool hasFunction = function != nullptr; diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index d0217f9c075..4c72a7a0a9b 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1150,11 +1150,6 @@ static bool astIsRhs(const Token *tok) return tok && tok->astParent() && tok == tok->astParent()->astOperand2(); } -static bool isVoidCast(const Token *tok) -{ - return Token::simpleMatch(tok, "(") && tok->isCast() && tok->valueType() && tok->valueType()->type == ValueType::Type::VOID && tok->valueType()->pointer == 0; -} - const Token* CheckUninitVar::isVariableUsage(const Token *vartok, const Library& library, bool pointer, Alloc alloc, int indirect) { const bool cpp = vartok->isCpp(); diff --git a/test/testother.cpp b/test/testother.cpp index a0583ec13df..cf834566646 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -3300,6 +3300,10 @@ class TestOther : public TestFixture { "};\n"); ASSERT_EQUALS("", errout_str()); + // #14136 + check("void f(int& x) { (void)x; }\n"); + ASSERT_EQUALS("", errout_str()); + check("void e();\n" "void g(void);\n" "void h(void);\n" @@ -12160,9 +12164,7 @@ class TestOther : public TestFixture { " for (auto &j : g(std::move(l))) { (void)j; }\n" " }\n" "}\n"); - ASSERT_EQUALS("[test.cpp:4:20]: (style) Variable 'j' can be declared as reference to const [constVariableReference]\n" - "[test.cpp:4:36]: (warning) Access of moved variable 'l'. [accessMoved]\n", - errout_str()); + ASSERT_EQUALS("[test.cpp:4:36]: (warning) Access of moved variable 'l'. [accessMoved]\n", errout_str()); } void moveCallback()