From 05b7173929aebac6e20270721af47fc3a7fdc9f4 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 3 Dec 2025 13:49:23 +0100 Subject: [PATCH 1/7] Update check64bit.cpp --- lib/check64bit.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/check64bit.cpp b/lib/check64bit.cpp index 794795eff26..801a649cd5d 100644 --- a/lib/check64bit.cpp +++ b/lib/check64bit.cpp @@ -40,6 +40,13 @@ namespace { Check64BitPortability instance; } +static bool isFunctionPointer(const Token* tok) +{ + if (!tok || !tok->variable()) + return false; + return Token::Match(tok->variable()->nameToken(), "%name% ) ("); +} + void Check64BitPortability::pointerassignment() { if (!mSettings->severity.isEnabled(Severity::portability)) @@ -103,7 +110,8 @@ void Check64BitPortability::pointerassignment() !tok->astOperand2()->isNumber() && rhstype->pointer == 0U && rhstype->originalTypeName.empty() && - rhstype->type == ValueType::Type::INT) + rhstype->type == ValueType::Type::INT && + !isFunctionPointer(tok->astOperand1())) assignmentIntegerToAddressError(tok); // Assign pointer to integer.. From 0cde666a2f639b5e750847c890eb1d379cd3f172 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 3 Dec 2025 13:54:35 +0100 Subject: [PATCH 2/7] Update test64bit.cpp --- test/test64bit.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/test64bit.cpp b/test/test64bit.cpp index 7a05bf75178..b0c55185648 100644 --- a/test/test64bit.cpp +++ b/test/test64bit.cpp @@ -67,6 +67,12 @@ class Test64BitPortability : public TestFixture { " t.a[i][j] = new std::vector;\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("int f();\n" // #11522 + "void g() {\n" + " int (*fp)() = *(int(*)())f;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void novardecl() { From 4278ee613dfa31d2c320cfd1a730c7b0c3146218 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 8 Dec 2025 10:12:53 +0100 Subject: [PATCH 3/7] Update tokenize.cpp --- lib/tokenize.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index da279b8f453..70ba8b2139e 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -674,7 +674,7 @@ namespace { return; mUsed = true; - const bool isFunctionPointer = Token::Match(mNameToken, "%name% )"); + const bool isFunctionPointer = Tokenizer::isFunctionPointer(mNameToken); // Special handling for T(...) when T is a pointer if (Token::Match(tok, "%name% [({]") && !isFunctionPointer && !Token::simpleMatch(tok->linkAt(1), ") (")) { @@ -1019,6 +1019,11 @@ namespace { }; } +bool Tokenizer::isFunctionPointer(const Token* tok) { + return Token::Match(tok, "%name% ) ("); +} + + void Tokenizer::simplifyTypedef() { // Simplify global typedefs that are not redefined with the fast 1-pass simplification. @@ -1088,7 +1093,7 @@ void Tokenizer::simplifyTypedef() typedefInfo.lineNumber = typedefToken->linenr(); typedefInfo.column = typedefToken->column(); typedefInfo.used = t.second.isUsed(); - typedefInfo.isFunctionPointer = Token::Match(t.second.nameToken(), "%name% ) ("); + typedefInfo.isFunctionPointer = isFunctionPointer(t.second.nameToken()); if (typedefInfo.isFunctionPointer) { const Token* tok = typedefToken; while (tok != t.second.endToken()) { @@ -1395,7 +1400,7 @@ void Tokenizer::simplifyTypedefCpp() } // function pointer - if (Token::Match(tokOffset2, "* %name% ) (")) { + if (isFunctionPointer(tokOffset2)) { // name token wasn't a name, it was part of the type typeEnd = typeEnd->next(); functionPtr = true; @@ -1622,7 +1627,7 @@ void Tokenizer::simplifyTypedefCpp() typedefInfo.lineNumber = typeName->linenr(); typedefInfo.column = typeName->column(); typedefInfo.used = false; - typedefInfo.isFunctionPointer = Token::Match(typeName, "%name% ) ("); + typedefInfo.isFunctionPointer = isFunctionPointer(typeName); if (typedefInfo.isFunctionPointer) { const Token* t = typeDef; while (t != tok) { @@ -7155,7 +7160,7 @@ void Tokenizer::simplifyFunctionPointers() while (Token::Match(tok2, "%type%|:: %type%|::")) tok2 = tok2->next(); - if (!Token::Match(tok2, "%name% ) (") && + if (!isFunctionPointer(tok2) && !Token::Match(tok2, "%name% [ ] ) (") && !(Token::Match(tok2, "%name% (") && Token::simpleMatch(tok2->linkAt(1), ") ) ("))) continue; @@ -7448,7 +7453,7 @@ void Tokenizer::simplifyVarDecl(Token * tokBegin, const Token * const tokEnd, co } // Function pointer if (Token::simpleMatch(varName, "( *") && - Token::Match(varName->link()->previous(), "%name% ) (") && + isFunctionPointer(varName->link()->previous()) && Token::simpleMatch(varName->link()->linkAt(1), ") =")) { Token *endDecl = varName->link()->linkAt(1); varName = varName->link()->previous(); @@ -9376,7 +9381,7 @@ Token* Tokenizer::getAttributeFuncTok(Token* tok, bool gccattr) const { if (Token::simpleMatch(prev, ")")) { if (Token::Match(prev->link()->previous(), "%name% (")) return prev->link()->previous(); - if (Token::Match(prev->link()->tokAt(-2), "%name% ) (")) + if (isFunctionPointer(prev->link()->tokAt(-2))) return prev->link()->tokAt(-2); } if (Token::simpleMatch(prev, ")") && Token::Match(prev->link()->tokAt(-2), "operator %op% (") && isCPP()) From e4036c4e7a3a1cb57fc30a7950f5477013971624 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 8 Dec 2025 10:13:22 +0100 Subject: [PATCH 4/7] Update tokenize.h --- lib/tokenize.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.h b/lib/tokenize.h index f9feebb43f0..16d74ae80e5 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -601,7 +601,7 @@ class CPPCHECKLIB Tokenizer { /** * Helper function to check whether number is one (1 or 0.1E+1 or 1E+0) or not? * @param s the string to check - * @return true in case is is one and false otherwise. + * @return true in case it is one and false otherwise. */ static bool isOneNumber(const std::string &s); @@ -613,6 +613,13 @@ class CPPCHECKLIB Tokenizer { */ static const Token * startOfExecutableScope(const Token * tok); + /** + * Helper function to check whether tok is the declaration of a function pointer + * @param the Token to check + * @return true in case tok is a function pointer and false otherwise. + */ + static bool isFunctionPointer(const Token* tok); + const Settings &getSettings() const { return mSettings; } From c70ec6203cd58fdb04a1af2fb579048c491f9374 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 8 Dec 2025 10:16:43 +0100 Subject: [PATCH 5/7] Update check64bit.cpp --- lib/check64bit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/check64bit.cpp b/lib/check64bit.cpp index bbcf3567e1f..63d01b96f89 100644 --- a/lib/check64bit.cpp +++ b/lib/check64bit.cpp @@ -52,7 +52,7 @@ static bool isFunctionPointer(const Token* tok) { if (!tok || !tok->variable()) return false; - return Token::Match(tok->variable()->nameToken(), "%name% ) ("); + return Tokenizer::isFunctionPointer(tok->variable()->nameToken()); } void Check64BitPortability::pointerassignment() From e20aaac2040551aaa6a6d1cf82d13732db647892 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 8 Dec 2025 10:47:21 +0100 Subject: [PATCH 6/7] Update tokenize.cpp --- lib/tokenize.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 70ba8b2139e..aaed296dc4c 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1023,7 +1023,6 @@ bool Tokenizer::isFunctionPointer(const Token* tok) { return Token::Match(tok, "%name% ) ("); } - void Tokenizer::simplifyTypedef() { // Simplify global typedefs that are not redefined with the fast 1-pass simplification. @@ -1400,7 +1399,7 @@ void Tokenizer::simplifyTypedefCpp() } // function pointer - if (isFunctionPointer(tokOffset2)) { + if (Token::Match(tokOffset2, "* %name% ) (")) { // name token wasn't a name, it was part of the type typeEnd = typeEnd->next(); functionPtr = true; From 7dfe32ef58d53df46e80a5cf06dcd8e34c1ee43e Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 8 Dec 2025 10:48:02 +0100 Subject: [PATCH 7/7] Update tokenize.h --- lib/tokenize.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tokenize.h b/lib/tokenize.h index 16d74ae80e5..d001c54cb10 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -615,7 +615,7 @@ class CPPCHECKLIB Tokenizer { /** * Helper function to check whether tok is the declaration of a function pointer - * @param the Token to check + * @param tok the Token to check * @return true in case tok is a function pointer and false otherwise. */ static bool isFunctionPointer(const Token* tok);