diff --git a/lib/checksizeof.cpp b/lib/checksizeof.cpp index 4f4a610ff..2d6d9ca98 100644 --- a/lib/checksizeof.cpp +++ b/lib/checksizeof.cpp @@ -250,6 +250,17 @@ void CheckSizeof::sizeofCalculation() for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { if (Token::simpleMatch(tok, "sizeof (")) { + + // ignore if the `sizeof` result is cast to void inside a macro, i.e. the calculation is + // expected to be parsed but skipped, such as in a disabled custom ASSERT() macro + if (tok->isExpandedMacro() && tok->previous()) { + const Token *cast_end = (tok->previous()->str() == "(") ? tok->previous() : tok; + if (Token::simpleMatch(cast_end->tokAt(-3), "( void )") || + Token::simpleMatch(cast_end->tokAt(-1), "static_cast")) { + continue; + } + } + const Token *argument = tok->next()->astOperand2(); if (argument && argument->isCalculation() && (!argument->isExpandedMacro() || printInconclusive)) sizeofCalculationError(argument, argument->isExpandedMacro()); diff --git a/test/testsizeof.cpp b/test/testsizeof.cpp index d681eb179..27eb063bf 100644 --- a/test/testsizeof.cpp +++ b/test/testsizeof.cpp @@ -108,6 +108,25 @@ private: check("sizeof(--foo)"); ASSERT_EQUALS("[test.cpp:1]: (warning) Found calculation inside sizeof().\n", errout.str()); + + // #6888 + check("int f(int i) {\n" + " $($void$)$sizeof$($i $!= $2$);\n" // '$' sets Token::isExpandedMacro() to true + " $($void$)$($($($($sizeof$($i $!= $2$)$)$)$)$);\n" + " $static_cast$($sizeof($i $!= $2$)$);\n" + " $static_cast$($($($($($sizeof$($i $!= $2$)$)$)$)$)$);\n" + " return i + foo(1);\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check("int f(int i) {\n" + " $sizeof$($i $!= $2$);\n" + " $($($sizeof($i $!= 2$)$)$);\n" + " return i + foo(1);\n" + "}"); + ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Found calculation inside sizeof().\n" + "[test.cpp:3]: (warning, inconclusive) Found calculation inside sizeof().\n", errout.str()); + } void sizeofForArrayParameter() {