From d1ca4e35544575269ca634951ef35edcf37d44ec Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 13 Sep 2024 21:08:41 +0200 Subject: [PATCH] Fix #13094 internalError for function pointer typedef (#6795) We have a block `// Special handling of function pointer cast` but the simplifications are incorrect. --- lib/tokenize.cpp | 4 ++-- test/testsimplifytypedef.cpp | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 597996a897e..9c531fcb1f5 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -752,9 +752,10 @@ namespace { return; mUsed = true; + const bool isFunctionPointer = Token::Match(mNameToken, "%name% )"); // Special handling for T(...) when T is a pointer - if (Token::Match(tok, "%name% [({]") && !Token::simpleMatch(tok->linkAt(1), ") (")) { + if (Token::Match(tok, "%name% [({]") && !isFunctionPointer) { bool pointerType = false; for (const Token* type = mRangeType.first; type != mRangeType.second; type = type->next()) { if (type->str() == "*" || type->str() == "&") { @@ -791,7 +792,6 @@ namespace { } // Special handling of function pointer cast - const bool isFunctionPointer = Token::Match(mNameToken, "%name% )"); if (isFunctionPointer && isCast(tok->previous())) { tok->insertToken("*"); Token* const tok_1 = insertTokens(tok, std::pair(mRangeType.first, mNameToken->linkAt(1))); diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index ad3bd5e439b..bab8ccc645e 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -233,6 +233,7 @@ class TestSimplifyTypedef : public TestFixture { TEST_CASE(simplifyTypedefFunction8); TEST_CASE(simplifyTypedefFunction9); TEST_CASE(simplifyTypedefFunction10); // #5191 + TEST_CASE(simplifyTypedefFunction11); TEST_CASE(simplifyTypedefStruct); // #12081 - volatile struct @@ -4315,6 +4316,27 @@ class TestSimplifyTypedef : public TestFixture { tok(code,false)); } + void simplifyTypedefFunction11() { + const char code[] = "typedef void (*func_t) (int);\n" + "void g(int);\n" + "void f(void* p) {\n" + " if (g != func_t(p)) {}\n" + " if (g != (func_t)p) {}\n" + "}\n"; + TODO_ASSERT_EQUALS("void g ( int ) ; " + "void f ( void * p ) { " + "if ( g != ( void ( * ) ( int ) ) ( p ) ) { } " + "if ( g != ( void ( * ) ( int ) ) p ) { } " + "}", + "void g ( int ) ; " + "void f ( void * p ) { " + "if ( g != void * ( p ) ) { } " + "if ( g != ( void * ) p ) { } " + "}", + tok(code,false)); + ignore_errout(); // we are not interested in the output + } + void simplifyTypedefStruct() { const char code1[] = "typedef struct S { int x; } xyz;\n" "xyz var;";