diff --git a/lib/checkother.cpp b/lib/checkother.cpp index af2ca4ea432..8eaea623500 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -313,13 +313,26 @@ void CheckOther::warningOldStylePointerCast() tok = scope->bodyStart; for (; tok && tok != scope->bodyEnd; tok = tok->next()) { // Old style pointer casting.. - if (!Token::Match(tok, "( const|volatile| const|volatile|class|struct| %type% * *| *| const|&| ) (| %name%|%num%|%bool%|%char%|%str%|&")) + if (tok->str() != "(") continue; + const Token* castTok = tok->next(); + while (Token::Match(castTok, "const|volatile|class|struct|union|%type%|::")) { + castTok = castTok->next(); + if (Token::simpleMatch(castTok, "<") && castTok->link()) + castTok = castTok->link()->next(); + } + if (castTok == tok->next() || !Token::simpleMatch(castTok, "*")) + continue; + while (Token::Match(castTok, "*|const|&")) + castTok = castTok->next(); + if (!Token::Match(castTok, ") (| %name%|%num%|%bool%|%char%|%str%|&")) + continue; + if (Token::Match(tok->previous(), "%type%")) continue; // skip first "const" in "const Type* const" - while (Token::Match(tok->next(), "const|volatile|class|struct")) + while (Token::Match(tok->next(), "const|volatile|class|struct|union")) tok = tok->next(); const Token* typeTok = tok->next(); // skip second "const" in "const Type* const" diff --git a/test/testother.cpp b/test/testother.cpp index 2c949a47877..3f938af2e85 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -1895,6 +1895,22 @@ class TestOther : public TestFixture { ASSERT_EQUALS("[test.cpp:2]: (style) C-style pointer casting\n" "[test.cpp:3]: (style) C-style pointer casting\n", errout.str()); + + // #12446 + checkOldStylePointerCast("namespace N { struct S {}; }\n" + "union U {\n" + " int i;\n" + " char c[4];\n" + "};\n" + "void f(void* p) {\n" + " auto ps = (N::S*)p;\n" + " auto pu = (union U*)p;\n" + " auto pv = (std::vector*)(p);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:7]: (style) C-style pointer casting\n" + "[test.cpp:8]: (style) C-style pointer casting\n" + "[test.cpp:9]: (style) C-style pointer casting\n", + errout.str()); } #define checkInvalidPointerCast(...) checkInvalidPointerCast_(__FILE__, __LINE__, __VA_ARGS__)